Oracle左连接(Left Join)结果不符合预期原因咨询
为什么两种左连接写法结果不同?
咱们来拆解下两个查询的执行逻辑,就能明白问题出在哪了:
第一种查询(不符合预期)的问题
你写的第一个左连接语句:
select * from days d left join order o on d.id= o.day where o.code = 0
它的执行顺序是:
- 先执行左连接:保留
days表的所有行,匹配到order表的行带上对应的order字段,没匹配到的行(也就是fr那一行),order表的所有字段都会是null。 - 再执行where过滤:
where o.code = 0会检查每一行的o.code值。但fr那行的o.code是null,在SQL里null和任何值比较的结果都是unknown,而where子句只会保留结果为true的行,所以这一行被直接过滤掉了,自然看不到fr的记录。
第二种查询(符合预期)的原理
第二个嵌套查询:
select * from (select * from days) d left join (select * from order where code = 0) o on d.id = o.day
执行顺序完全不同:
- 先执行子查询过滤
order表:select * from order where code = 0会先把code不等于0的行(比如order 3那行code=2)提前过滤掉,得到一个只包含code=0的order子表。 - 再执行左连接:用
days表左连接这个已经过滤好的子表。这时候days表的所有行都会被保留,fr那行没有匹配的子表记录,所以order和code字段显示null,刚好符合你的预期。
更简洁的优化写法
其实不用嵌套子查询,把o.code=0的条件放到on子句里也能得到正确结果:
select d.description, o.order, o.code from days d left join order o on d.id = o.day and o.code = 0
因为on子句是在连接阶段就应用条件,只会匹配order表中code=0的行,同时保留days表的所有行,效果和嵌套子查询一样,但写法更简洁。
内容的提问来源于stack exchange,提问作者user9741285
相关产品推荐
相关产品推荐

