[英]MySQL placement of conditions in on-clauses of multiple outer joins
作为后续工作, 在SQL / MySQL中,join语句中的“ ON”和“ WHERE”之间有什么区别? 和SQL加盟:where子句主场迎战一对条款 - 这非常重要,如果条件放在上子句与在WHERE子句中的外部联接。
但是,当有多个外部联接时,条件放在哪个子句上是否重要?
例如,这些会产生不同的结果吗?
select * from t1 left join t2 on t1.fid=t2.id and t2.col=val
left join t3 on t2.fid=t3.id;
VS:
select * from t1 left join t2 on t1.fid=t2.id
left join t3 on t2.fid=t3.id and t2.col=val;
绝对是不同的。
t2.col=val
查询将仅包含满足t2
行t2.col=val
第二个查询将包括所有t2
行,并且仅当t2.col=val
时列出t3
查询不等效。 构造一个反例很容易:
create table t1 (id int not null, val int not null);
create table t2 (id int not null, val int not null);
create table t3 (id int not null, val int not null);
insert into t1 (id, val) values (1,1);
insert into t2 (id, val) values (1,1);
insert into t3 (id, val) values (1,1);
select * from t1
left join t2
on t1.id = t2.id
and t2.val = 2
left join t3
on t2.id = t3.id;
+----+-----+------+------+------+------+
| id | val | id | val | id | val |
+----+-----+------+------+------+------+
| 1 | 1 | NULL | NULL | NULL | NULL |
+----+-----+------+------+------+------+
select * from t1
left join t2
on t1.id = t2.id
left join t3
on t2.id = t3.id
and t2.val = 2;
+----+-----+------+------+------+------+
| id | val | id | val | id | val |
+----+-----+------+------+------+------+
| 1 | 1 | 1 | 1 | NULL | NULL |
+----+-----+------+------+------+------+
这是查询之一:
select *
from t1 left join
t2
on t1.fid = t2.id left join
t3
on t2.fid = t3.id and t2.col = val;
是的,结果不同。 如果您使用inner join
它们将是相同的,但是left join
改变事情-因为join
子句不会对行进行任何过滤。
我认为最简单的解释是t1
和t2
之间的t2.col <> val
将包括t1
所有行以及t2
所有匹配行-甚至包括那些t2.col <> val
。 这些保留在结果集中,因为下一个left join
不会将它们过滤掉。
实际上,第二个on
子句中的条件t2.col = val
不会影响结果集中的行。 如果存在匹配项,则t3
的行将基于第一个条件停留。 如果没有匹配项,则t3
的行仍在结果集中-但t3
列将为NULL
。
在此版本中:
select *
from t1 left join
t2
on t1.fid = t2.id and t2.col = val left join
t3
on t2.fid = t3.id;
第一个t2.col = val
从t1
获得所有行,并且仅从t2
获得匹配行,其中t2.col = val
。 然后,第三个联接可以添加更多行。
注意:在某些情况下,两个查询将返回相同的结果。 但是,以下数据将产生不同的结果(假设val = 0):
T1
fid
1
T2
fid col
1 0
1 1
T3
id
1
在第二个on
子句中具有条件的查询将返回:
1 1 0 1
1 1 1 NULL
在第一个on
子句中具有条件的查询将返回:
1 1 0 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.