在myql的sql查询中,left join使用越来越多,工作中也遇到了一些问题,left join返回结果中有重复的数据。
建立两张表模拟场景A表,B表如下,A表代表学生表,B表为学生选修的课程表。
DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL,
`sex` varchar(255) DEFAULT NULL,
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of a
-- ----------------------------
INSERT INTO `a` VALUES ('1', '小明', '男');
INSERT INTO `a` VALUES ('2', '小东', '男');
INSERT INTO `a` VALUES ('3', '小西', '女');
DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`Aid` int(11) DEFAULT NULL,
`course` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
UNIQUE KEY `id` (`id`),
KEY `Aid` (`Aid`),
CONSTRAINT `aa` FOREIGN KEY (`Aid`) REFERENCES `a` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of b
-- ----------------------------
INSERT INTO `b` VALUES ('1', '1', '语文类型A', '文科');
INSERT INTO `b` VALUES ('2', '2', '数学', '理科');
INSERT INTO `b` VALUES ('4', '1', '英语', '文科');
如果要查询学生表名字带有明的,并且选修了类型是文科的学生信息,
写下如下sql
select a.*from a LEFT JOIN b on a.id=b.Aid where a.name like '%明%'
and b.type like '%文科%'
查询结果看sql上面的截图,这时候查出来的数据会有重复记录,原因就在于
b表中的学生的aid是有两条记录的,也就是a==>b表如果是1对多的关系,
用left join查询会有重复数据。
在工作中left join的情况往往不会很简单,不能直接使用group by 去重,例如如果像以下的场景写sql直接报错。
select a.*,b.type from a as a LEFT JOIN b as b on a.id=b.Aid where a.name like '%明%'
and b.type like '%文科%' GROUP BY a.id order by a.id,a.name
该条sql是想同时查出a、b两个表的信息,并且要根据a表和b表的条件做限定数据。
select a.*from a LEFT JOIN b on a.id=b.Aid where a.name like '%明%'
and b.type like '%文科%' group by a.id
类似4.1 这样的复杂sql,应该使用distinct去重即可,如下写法
select DISTINCT a.*,b.type from a as a LEFT JOIN b as b on a.id=b.Aid where a.name like '%明%'
and b.type like '%文科%' order by a.id,a.name
需要注意的是如果distinct在最外层,order by在里层,会使order by的排序失效,类似 select distinct from( select *from xxx order by xxx);类似这种,会失效,需要把order by也移动到外边。
本文是我对于目前left join的目前解决办法,如果有更好的解决办法,欢迎同学们指出,共同进步,共同学习。