- 联系方式: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
的执行流程,写点东西出来以供后面回顾