[英]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.