2016-03-21 55 views
6

我一直在使用這個,所以現在是充分了解它的時候了。假設這樣的查詢:多個LEFT連接 - 什麼是「左」表?

SELECT 
    * 
FROM a 
LEFT JOIN b ON foo... 
LEFT JOIN c ON bar... 

documentation告訴我們,進行

T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 ON boolean_expression

LEFT OUTER JOIN

首先,內連接。然後,對於T1中不滿足與T2中的任何行的連接條件的每一行,聯合行將在T2的列中添加空值。因此,對於T1中的每一行,連接表總是至少有一行。

問題很簡單:在這種情況下什麼是T1?是a?或者是a LEFT JOIN b ON foo? (或者它是一樣的嗎?)

+1

根據你如何加入數據(你的例子中的foo和bars),例如,如果在語句「... JOIN c ON bar ...」中,條件使用表a和b ,它將成爲JOIN b ON foo。 –

+2

'(左連接b)左連接c',即第一個'a'是左表,然後'(左連接b)'是下一個左表。 – jarlh

+0

@ jarlh如果你把它寫成答案並提供參考資料,我會接受它 – vektor

回答

3

一個FROM條款解析由左到右(除非用括號覆蓋)的條件:

在最後一種情況,如果你寫這樣將是對可讀性的改善。所以:

FROM (
     a 
     LEFT JOIN b 
      ON foo... 
    ) 
LEFT JOIN c 
    ON bar... 

這在documentationFROM條款的join-type部分解釋:

使用括號如果需要確定的順序

FROM a 
LEFT JOIN b 
    ON foo... 
LEFT JOIN c 
    ON bar... 

如解析築巢。在 沒有括號,JOIN從左到右嵌套。在任何情況下,JOIN 比分隔FROM -list項目的逗號的綁定更緊密。

因此,一系列LEFT JOIN s保留了第一個提到的表中的所有記錄。這是一個方便。

請注意,無論連接類型如何,FROM子句的解析都是相同的。

+0

我已經調整了您的示例中的縮進以更強調括號。如果你不同意這個看起來更好,請隨時回覆我的道歉。 :) – IMSoP

+0

@IMSoP。 。 。我非常強烈地反對它更好,但我不會改變它。 –

0

這裏是多連接操作。 SQL是一種描述獲取結果的語言,而不是如何獲取它們。優化器將決定首先執行哪個連接,具體取決於它認爲最有效的連接。 你可以閱讀一些資料
https://community.oracle.com/thread/2428634?tstart=0
我認爲,它適用於PostgreSQL的

+0

你能否提供一些參考? – vektor

+0

對不起,第一個錯誤的答案。 –

+0

@格萊斯。 。 。語義順序(如何解釋連接)與執行順序(如何實現連接)無關。因此,你已經回答了一個不同的問題。 –

0

同樣這可能是兩個,這取決於你如何連接(在你的例子中,foo和酒吧)的數據。

例如,如果在你的例子中,你想加入一個與b和一個與c,T1將是一個。

但是,如果你的意圖是加入一個b和與c的結果,那麼T1將是一個左加入b ON foo。

(a LEFT JOIN b ON foo) LEFT JOIN c ON bar