2016-01-15 61 views
0

這可能是重複的,但我不知道如何正確搜索。我可以寫基本的SQL,並且知道'笛卡爾積'的概念。但我總是在某種程度上對加入感到困惑。實施例中的sqlserver:sql join'on'operator not filtering

A | B 
--+-- 
1 | 2 
2 | 3 

select * from ta left join tb on ta.A = 2  --??! 

A | B 
--+-- 
1 | Null 
2 | 2 
2 | 3 

select * from ta left join tb on tb.B = 2 --seems easier to understand 

A | B 
--+-- 
1 | 2 
2 | 2 

能任一項解釋第一SQL(上ta.A = 2),爲什麼是A列不過濾。順便說一下,我知道ta.ColA = tb.ColB最常見的用法,但在這個問題中,我只是想知道是如何工作的。

+0

您在輸出中出現錯誤,導致難以理解問題。在你的第一個輸出中,第二行應該有'A = 2',而不是'A = 1'。 –

+0

對不起,我更新了它。 –

回答

3

一個LEFT JOIN始終遵循以下規則:

  1. 採取的所有行的左側加入
  2. 從聯接的右側找到任何匹配的行,並使用ON ...條款找到那些行。
  3. 根據從右邊出現的行數,請執行下列操作:
    • 沒有行:從左側的結果產生單列,並會一直都列來自右側NULL
    • 一行:從左側的單排從右側合併單列
    • 多行:從左側與每個從右側的行的合併單排,產生多個行中的輸出

因此,您的ON TA.A=2僅用於從右側過濾行。

現在,您在您的問題中出現錯誤,這使得僅僅閱讀問題變得更困難。

此輸出:

A | B 
--+-- 
1 | Null 
1 | 2    <-- notice A=1 here, this is incorrect 
2 | 3 

應該是這樣的:

A | B 
--+-- 
1 | Null 
2 | 2    <-- notice A=2 here 
2 | 3 

基本上,你的查詢做到這一點:

  • 採取的所有行TA
  • TB查找行其中TA.A=2是真的,這隻會發生在當你在A=2行時,這就是爲什麼你有NullA=1
  • 由於您沒有指定所需的TB行中的哪一行,因此所有這些行都將與單行A=2合併。
+0

真的值得將「一行」和「多行」分隔開來嗎? –

+0

從經驗中解釋給別人,我會說是。 –

3

LEFT JOIN中,加入左側的所有行將始終保留ON條件確定是否有任何來自右側的行將成功連接到這些行。

所以,

select * from ta left join tb on ta.A = 2  --??! 

A | B 
--+-- 
1 | Null 
2 | 2 
2 | 3 

A等於1,病情ta.A = 2是不正確的,所以從沒有tb保留。

A等於2,條件ta.A = 2爲真,所以從所有tbta接合到這樣的行。

+0

接受另一個,因爲他不僅回答了,而且糾正了原始輸出中的錯誤。但是,你快! –