使用左(或外)连接时,您必须考虑何时施加数据限制与创建笛卡尔时的时间.
假设您想要来自一个表(A)的所有记录,并且只想要在另一个表(B)中匹配的那些记录.执行连接时,B中将出现NULL值(不匹配的记录到A).在B字段中添加限制条件(where子句)实际上会从A中删除您想要的记录;作为where子句在连接之后执行.这与您开始使用INNER JOIN的效果相同!
通过在使用外连接时将B表上的限制条件移动到连接,可以避免这种情况.这样,在施加限制之后生成笛卡尔,确保表A中的“所有记录”保持所有记录.如果没有在连接上,正如您所见,限制是在笛卡尔坐标之后施加的,因此删除了空值,并且您不再获得“所有记录”,因此取消了LEFT连接.这就好像你在第一时间做INNER连接一样.这就是为什么做一个OR语句来返回空值,并且该值也有效,但只有当它是一个NOT NULL列(或者null的类型没有语义含义)时,LC在下面的注释中指出.
在这种情况下,good.type的where子句正在消除左连接的结果,因此要么在生成笛卡尔坐标之前将标准添加到强制限制的连接(允许空值存在)
select *
from recipe_qa as bad
left join recipe_qa as good
on good.id = bad.id
and good.type = 'perfect'
where bad.type = 'discard'
或使用is null条件不从左连接中排除记录.这有一些风险在以下评论中提出.
select *
from recipe_qa as bad
left join recipe_qa as good
on good.id = bad.id
where bad.type = 'discard'
and (good.type = 'perfect' or good.type is null)