目录
一、背景
二、探究
2.1、统计每个班级中女生的数量
错误的写法
查询结果
正确的写法
查询结果
2.2、只统计"一班"的学生数量
错误的写法
查询结果
正确的写法
查询结果
三、总结
一、背景
在一次对数据进行统计的时候,需要对两张表进行关联,类似于这样的语句a left join b on a.id = b.id where b.name = xx。发现最终的结果和预期不一致,汇总之后的数据变少了。
一开始还比较费解,后面回过神来才发现,犯了一个低级的错误,就是在使用left join时过滤条件放到on后面还是where后面是有区别的,如果没有搞清楚他们的区别,连表汇总的结果就会变少或者变多。
二、探究
student表
classes表
2.1、统计每个班级中女生的数量
错误的写法
select a.name, count(b.name) as num from classes a left join students b
on a.id = b.class_id
where b.gender = 'F'
group by a.name
查询结果
正确的写法
select a.name, count(b.name) as num
from classes a left join students b
on a.id = b.class_id and b.gender = 'F'
group by a.name
查询结果
2.2、只统计"一班"的学生数量
错误的写法
select a.name, count(b.name) as num
from classes a left join students b
on a.id = b.class_id and a.name = '一班'
group by a.name
查询结果
正确的写法
select a.name, count(b.name) as num
from classes a left join students b
on a.id = b.class_id
where a.name = '一班'
group by a.name
查询结果
问题一错误的原因:由于在where条件中对右表限制,导致数据缺失(四班应该有个为0的结果)。
问题二错误的原因:由于在on条件中对左表限制,导致数据多余(其他班的结果也出来了,还是错的)。on 后跟关联表(从表)的过滤条件,如果再加筛选条件只针对关联表!
on 后跟关联表(从表)的过滤条件,where 后跟主表或临时表的筛选条件(左连接为例,主表的数据都会查询到,所以临时表中必定包含主表所有的字段,需要给主表加什么筛选条件,直接给临时表加效果相同) 。
三、总结
通过上面的问题现象和分析,可以得出了结论:在left join语句中,左表过滤必须放where条件中,右表过滤必须放on条件中,这样结果才能不多不少,刚刚好。