2011-01-14 42 views
1

這裏是我的數據左連接TransactSQL返回我意外的結果 - 我對左連接的理解是錯誤的嗎?

CREATE TABLE TempA ( 
    ID INT IDENTITY(1,1), 
    Msg VARCHAR(20) 
) 

INSERT INTO TempA (Msg) values ('a') 
INSERT INTO TempA (Msg) values ('b') 
INSERT INTO TempA (Msg) values ('c') 

CREATE TABLE TempB ( 
    ID INT IDENTITY(1,1), 
    Msg VARCHAR(20) 
) 

所以TempB是空的。現在我運行以下查詢

select a.* 
    from TempA a 
left JOIN TempA B on a.id = b.id 

它從TempA返回3行,如預期的那樣好,至今爲止。讓我們在上面的查詢中添加一個過濾器

select a.* 
    from TempA a 
left JOIN TempA B on a.id = b.id 
    where b.msg = 'aa' 

它不返回任何行給我。我認爲,因爲它是一個左連接,我應該從TempA表中獲得3行。我錯了嗎?

+2

注意:所有的例子查詢是自聯接。我認爲你的意思是第二張桌子是「TempB」。這可以解釋爲什麼下面的答案不起作用。 – Bill 2011-01-14 19:48:55

回答

4

通過在where子句的使用中包含b.msg過濾器,您正在將左連接轉換爲內連接。

select a.* from TempA a left JOIN TempB B on a.id = b.id and b.msg = 'aa' 

(概念)連接謂詞情況,請從非加入行會添加回來,將有你的過濾器再次排除這些行NULLb.msg那麼價值!

您可能想要查看伊茨克奔甘的Logical Query Processing Poster

+0

可否請您詳細說明一下它是如何轉換爲內部連接的? – imak 2011-01-14 19:33:02

+0

您的where條件`b.msg ='aa'`永遠不會對於由所有`b`列的連接輸出的任何行爲true,因爲`on`條件不匹配;所以連接*有效地作爲內部連接。 – araqnid 2011-01-14 19:34:43

+0

這樣想,FROM子句及其所有連接都決定了一個初始數據集。然後WHERE子句過濾掉東西。如果將過濾器置於LEFT JOIN中,則會從「A」中獲取所有行,以及任何「B」記錄與連接條件相匹配。嘗試在您的選擇中包含b.msg。在你的例子中,它們都是NULL。現在將條件移至WHERE子句。 b.msg = NULL的所有記錄(因爲不匹配)被過濾掉。 – Bill 2011-01-14 19:46:21

1

我perfer馬丁的解決方案,但另一種選擇是

select a.* 
from 
    TempA a 
    left JOIN TempB B on a.id = b.id 
where b.msg = 'aa' or b.msg is null 
+0

這不會給我任何結果 – imak 2011-01-14 19:35:00

2

當使用OUTER JOIN,在WHERE款規定的標準是後應用加入。因爲沒有行,其中b.msg ='aa',所以不會返回任何行。

ON子句中指定的標準,該標準被應用之前的JOIN,所以b引用將只受到影響。在此示例中,b引用將返回NULL,而a引用不受影響。

4

以下是發生了什麼;

你有兩個表。

TempA ID Msg 
     -- --- 
     1 a 
     2 b 
     3 c 

TempB ID Msg 
     -- --- 

現在,當你這樣做的加入,最初的結果看起來是這樣的:

Result a.ID a.Msg b.ID b.Msg 
     ---- ----- ---- ----- 
     1 a  NULL NULL 
     2 b  NULL NULL 
     3 c  NULL NULL 

當篩選與WHERE子句查詢,你過濾掉任何不具有一個b.Msg'aa'。那會過濾掉全部的記錄,因爲他們都有b.MsgNULL。讓你有這樣的:

Result a.ID a.Msg b.ID b.Msg 
     ---- ----- ---- ----- 

然後,你只選擇這使得這個最終結果從TempA列:這取決於你怎麼做過濾

Result a.ID a.Msg 
     ---- -----