Join

多個內部連接返回什麼交集?

  • November 14, 2017

如果我有疑問:

SELECT * FROM A
INNER JOIN B ON B.ID = A.ID
INNER JOIN C ON C.ID = B.ID

這是否會為此查詢返回不同的結果?

SELECT * FROM A
INNER JOIN B ON B.ID = A.ID
INNER JOIN C ON C.ID = A.ID

在我看來,在第一個查詢中,我會得到 A、B、C 的交集。在第二個查詢中,我會得到 A、B 的交集和 A、C 的交集。

如果是這種情況,我會在 B/C 的列中找到 NULL 值,而 B、C 之間沒有交集嗎?

不,這兩個查詢是相同的。

既然A.ID = B.IDA.ID = C.ID,那麼根據定義B.ID = C.ID

對於任何給定的 ID x,如果在AID 中有一行,在 ID 中有一行B,但在 ID 中沒有行C,則來自Aand的B行將被忽略,因為兩個連接都是INNER JOINs。當然,對於A-C-B和也是如此。B-C-A

因此,當所有JOINs 都是INNER JOINs時,獲取給定列的唯一方法NULL是該列是否NULL在現有行中 - 您不能NULL在一個表中填寫 s 行,因為沒有匹配的行,因為缺少一個INNER JOINed 表中的匹配行表示其他表中的行無效。

換句話說 - 對於 中的給定行B,如果 中沒有匹配的行,那麼使用該行C的行也沒有匹配。該行(以及與其匹配的任何行)將不包括在內,因為所有**ed tables都必須存在一行。A JOIN B``B``B``AINNER JOIN


A INNER JOIN B RIGHT OUTER JOIN C如果查詢是或,您詢問是否有任何變化A LEFT OUTER JOIN B INNER JOIN C

它可以改變。

在正常情況下,連接將從左到右進行評估(即從第一個列出的連接到最後一個連接)。

如果由於某種原因您必須修改該行為,您可以通過移動ON子句的位置來實現。根據您的 DBMS,您可能還必須添加括號來指示應評估子句的順序(我嘗試了 MS SQL 和 MySQL;MySQL 需要括號才能工作,MS SQL 允許但不需要它們)。我在下面的範例中包含了括號,這些括號不會從左到右進行評估,以幫助說明這一點。

例子:

  • A INNER JOIN B ON <condition1> RIGHT OUTER JOIN C ON <condition2>

這將首先連接AB(需要匹配<condition1>以關聯兩個表中的行),然後執行右外連接到C(將返回C滿足WHERE條件的所有行,並將與A-B連接中的任何行相關聯<condition2>滿足。

  • A INNER JOIN (B RIGHT OUTER JOIN C ON <condition1>) ON <condition2>

另一方面,這將連接 B 和 C(包括來自 的所有C符合WHERE子句的行,與來自該的B任何行相關聯和基於 的匹配行。請注意,在這裡,您得到不同的結果和,因為所有行都將具有非 NULL ,但在沒有來自 的匹配行的情況下將為 NULL 。<condition1>``B-C``A``A``B-C``<condition2>``A.id - B.id``A.id = C.id``C.id``B.id``B

  • A LEFT JOIN B ON <condition1> INNER JOIN C ON <condition2>

對於ON通常位置的子句,這是從左到右評估的。因此,首先我們從 中獲取所有行A,將它們與B基於<condition1>;的任何匹配行相關聯。然後,我們對與 的連接結果進行內部連接A-BC僅返回其中一行 from與基於的行A-B匹配的行。C``<condition2>

  • A LEFT JOIN (B INNER JOIN C ON <condition1>) ON <condition2>

在這裡,我們再次強制B-C內部連接首先發生,因此當來自B的行與來自的行匹配時,我們會得到行Cbased on <condition1>; 然後,我們獲取B-C內部連接的結果並將其匹配到A(從 中返回所有行A,以及B-C基於<condition2>

ON這是幾個 SQLFiddle 連結,它們顯示了當您在子句中移動時這些連接的結果:一個用於MySQL,一個用於MS SQL Server

注意:我沒有說這如何與非 ANSI 連接語法一起工作。如果你不知道我在說什麼 - 感謝你的幸運星並繼續前進。我不確切知道優先級如何與該語法一起使用。我希望它能夠通過表格列表,從左到右(首先提到到最後)。顯然,由於沒有ON條款,因此這些條款沒有影響。可能有辦法強制那裡的順序(也許又是括號,大概在FROM子句中?),但我不知道答案。由於大多數人(包括我自己)強烈建議不要嘗試為您JOIN的 s 使用該語法,我將簡單地使用它來避免這個問題:-)。

引用自:https://dba.stackexchange.com/questions/190863