- 联系方式:1761430646@qq.com
- 编写时间:2022年10月30日14:51:42
- 菜狗摸索,有误勿喷,烦请联系
1. SQL的左外连接理解
1.1 环境假设
-
假设现在有两个表,其数据如下所示

-
注意:右表的
left_id字段是此表的外键,指向左表的id主键字段
1.2 SQL分析
-
对于左外连接,其左表的所有数据都会保留下来,并用左表的每一条数据根据
on后面的条件(where之前)跟右表数据进行逻辑处理,如果为true,则右表这条记录对应字段会显示原值,否则对应字段全为NULL -
select * from l left join r on l.id = r.left_id-
其查询结果如下

-
分析
-
根据
l.id = r.left_id这个判定条件,逐一拿取左表的每一条数据,对于这每一条数据,都会遍历右表的所有记录,通过判定条件的真假来决定是否保留右表的字段值 -
左表
id值为1的记录,对应右表的left_id字段值为1的刚好有一条记录,所以有了结果图的第一行数据
-
坐标
id值为2的记录,对应右表的left_id字段值为2的有两行记录,所以有了结果图的第二、三行数据
-
左表
id值为3的记录,对应右表的left_id字段值为3的没有任何匹配记录,所以有了结果图的第四行数据,右表的所有字段值均为NULL
-
-
-
select * from l left join r on l.id = b.left_id and r.r_type = '右t'-
其查询结果如下

-
分析
- 其执行原理如上一条
SQL所示,只不过这个判定条件多了个判定逻辑而已
- 其执行原理如上一条
-
-
select * from l left join r on l.id = b.left_id where r.r_type = '右t'-
其查询结果如下

-
注意:
-
虽然说这一条
SQL的查询结果跟上一条SQL语句select * from l left join r on l.id = b.left_id and r.r_type = '右t'查询出来的结果一模一样 -
但是它们的查询流程是不太一样的
-
对于上一条
SQL,它是直接在左外连接时期通过判定条件l.id = b.left_id and r.r_type = '右t'过滤查询出来的结果构成了结果集 -
而对于本
SQL,它的最终结果集实际上是经过了两层处理,-
一是在左外连接时期通过判定条件
l.id = b.left_id生成临时结果集T,其如下图所示
-
二是在临时结果集T的基础上,通过
where的判定条件r.r_type来过滤数据,生成最终的结果集
-
-
-
1.3 一点小结
- 一开始我也觉得我也很懂这个左外连接
- 但是在这次实习过程中,改
SQL的时候突然觉得很懵逼,自己脑子里下意思忽略了当右表没有满足on判定条件处理时的情况 - 导致疑神疑鬼
- 借此机会顺便探究下
on和where的执行流程,写点东西出来以供后面回顾