上一篇对三个join的语句做了一个区别,如果连最基础的都不清楚,那么请先参考:inner join 与 left join 和right join之间的区别
碰巧在项目中遇到了一个sql,是left join和where的条件限制的区别,想了好半天,这里做一下笔记,万一以后忘记了方便查看。
话不多说,直接上测试数据和sql,然后对我的理解进行分析下。
student表和grade表
简单提一个需求是:我需要统计所有有成绩的学生信息。项目遇到那个问题比这个复杂,但是最终需要筛选的条件和这个大致相同,这里就举个栗子。
这里分析一下,既然是学生信息,那么,肯定就是以student为主表,关联的为grade表,写出下面条件。
SELECT stu.* FROM student stu LEFT JOIN grade gra on stu.id = gra.c_stuId AND gra.c_fs IS NOT NULL
查询结果如下:
仔细看看上面的sql,和需求,好像也没有什么错误呀,分数不为空,我的确是加了限制条件了啊, LEFT JOIN grade gra on stu.id = gra.c_stuId AND gra.c_fs IS NOT NULL
但是看看需求,是分数不为空的学生,但是李四的成绩的确是空的,结果还是查出来了,咦,那么就奇怪了,问题出在哪里了呢。
这就回到之前我们所说的,left join并不会影响主表,也就是说,无论LEFT JOIN on后面什么条件,主表学生成绩都会被查出来,所以说,这里的限制条件没用。
这时候就需要where这个老大上场了。将上面查询sql修改如下:
SELECT stu.* FROM student stu LEFT JOIN grade gra on stu.id = gra.c_stuId WHERE gra.c_fs is NOT null
查询结果如下:
咦,是吧,达到了预期的目的,id为3的学生分数是空的,那么最后查询出来的也没有包含他。这就是where的厉害之处。
那么,到底是为什么呢,我们说下,on只是对局部条件做限制,而where是对全局做限制,什么是全局做限制呢,也就是相当于,对最后查询出来的整个结果做限制。其实我们可以把
所有的字段都查出来,然后看一下,就一目了然了。
为了方便我就直接截图说明:
加上gra.*一看就知道,查询出来的整个数据就是如上所示,而where的作用是什么呢,是对全局进行限制,就相当于上面查询出来的又是一个新的表,我来对这个做限制。
如图所示:
where加上就相当于对这个结果集再次进行限制,把分数为空的去掉了,最终结果如下:
但是因为我们查询的时候,如上图所示红色方框所显示的,并没有查询出来,所以并不能一目了然的看到分数这个字段,因此会产生一开始所看到的那种情况,另外也是因为之间没接
触过,以前以为where条件只能针对主表字段去做一个筛选,并不能筛选从表的,现在经过上面一个小案例之后,算是有了一个大概的理解了,不知道有没有对你产生帮助,欢迎下方
评论,一起探讨。!!