很容易理解为什么左外连接不是可交换的,但是我在理解它们是否是关联时遇到了一些麻烦.一些在线消息来源表示他们不是,但我没有设法说服自己这是事实.
假设我们有三个表:A,B和C.
令A包含两列,ID和B_ID,其中ID是表A的主键,B_ID是对应于表B的主键的外键.
令B包含两列,ID和C_ID,其中ID是表B的主键,C_ID是对应于表C的主键的外键.
设C包含两列,ID和VALUE,其中ID是表C的主键,VALUE只包含一些任意值.
那么不应该(左外连接B)左外连接C等于A左外连接(B左外连接C)?
解决方法
如果你假设你正在加入一个外键,正如你的问题似乎暗示,那么是的,我认为OUTER JOIN保证是关联的,如
Przemyslaw Kruglej’s answer所述.
但是,鉴于您实际上没有指定JOIN条件,迂腐正确的答案是否,它们不能保证是关联的.有两种简单的方法可以违反与反常ON条款的关联性.
1.其中一个JOIN条件涉及所有3个表中的列
这是违反关联性的一种非常便宜的方式,但严格来说,在你的问题中没有任何内容可以禁止它.使用问题中建议的列名称,请考虑以下两个查询:
-- This is legal SELECT * FROM (A JOIN B ON A.b_id = B.id) JOIN C ON (A.id = B.id) AND (B.id = C.id) -- This is not legal SELECT * FROM A JOIN (B JOIN C ON (A.id = B.id) AND (B.id = C.id)) ON A.b_id = B.id
底部查询甚至不是有效查询,但顶部查询是.显然,这违反了相关性.
2.尽管一个表中的所有字段都是NULL,但可以满足其中一个JOIN条件
这样,我们的结果集中甚至可以有不同数量的行,具体取决于JOIN的顺序.例如,让B上JOINing A的条件为A.b_id = B.id,但C上JOINing B的条件为B.id IS NULL.
SELECT * FROM (A LEFT OUTER JOIN B ON A.b_id = B.id) LEFT OUTER JOIN C ON B.id IS NULL; SELECT * FROM A LEFT OUTER JOIN (B LEFT OUTER JOIN C ON B.id IS NULL) ON A.b_id = B.id;
你可以在这里看到这个:http://sqlfiddle.com/#!2/0d462/3