2017-02-17 47 views
1

我已經閱讀了SO的許多帖子,並且我理解了where子句和on子句之間的區別。但其中大部分示例都是在RIGHT表格上過濾(使用左連接時)。如果我有如下查詢:左加入之前的SQL過濾器左表

select * from tableA A left join tableB B on A.ID = B.ID and A.ID = 20 

返回值不是我所期望的。我會認爲它首先過濾左邊的表格,並只提取ID = 20的行,然後用tableB進行左邊的連接。

當然,這應該是技術上一樣做:

select * from tableA A left join table B on A.ID = B.ID where A.ID = 20 

但我認爲表現會更好,如果你可以做一個加入之前過濾表。有人能夠告訴我如何處理這個SQL,並幫助我徹底理解這一點。

回答

3

A left join遵循一個簡單的規則。它將所有行保留在第一個表中。列的取決於on子句。如果沒有匹配,那麼對應表的列是NULL - 無論是第一個還是第二個表。

因此,對於這個查詢:

select * 
from tableA A left join 
    tableB B 
    on A.ID = B.ID and A.ID = 20; 

所有A行是在結果集中,而不管是否有匹配。當id不是20時,行和列仍然取自A。但是,條件是錯誤的,因此B中的列是NULL。這是一條簡單的規則。它不取決於條件是在第一張桌子還是在第二張桌子上。

對於此查詢:

select * 
from tableA A left join 
    tableB B 
    on A.ID = B.ID 
where A.ID = 20; 

from條款保留中的所有行A。但是where條款有其效果。然後它過濾行,只有id 20位於結果集中。

當使用left join

  • 上第一臺過濾條件的where子句中去。
  • 後續表格的過濾條件進入on子句。
+0

感謝您的回覆,但您可否詳細說明「當ID不是20,那麼列值爲NULL」。你的意思是tableB的ID不是20,那麼tableB中的所有列將爲空?這有一個用例嗎?或者應該在第一張桌上的過濾總是去哪裏? – TFK

+0

@TFK。 。 。我修正了措辭。 –

0

你來自哪裏TableA的有,你可以把一個子查詢像(選擇X *從表A X其中x.value = 20)TA

然後參考TA像你這樣TableA的前面。

可能查詢優化器會爲您做這件事。

Oracle應該有辦法顯示查詢計劃。在sql語句之前加上「解釋計劃」。兩種方式看看計劃,看看它做了什麼。

+0

您在邏輯上是正確的,但優化器不會重寫它;它是一個OUTER JOIN操作符。 – BobC

0

在您的第一條SQL語句中,A.ID=20未在技術上加入任何內容。連接用於將兩個單獨的表連接在一起,ON語句通過將它們作爲關鍵字進行關聯來加入列。

WHERE語句允許通過減少只有在該特定列下可以找到該值的位置返回的行數來過濾數據。