簡體   English   中英

MySQL在多個外部聯接的子句中放置條件

[英]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查詢將僅包含滿足t2t2.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子句不會對行進行任何過濾。

我認為最簡單的解釋是t1t2之間的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 = valt1獲得所有行,並且僅從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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM