2013-10-10 44 views
2

我想了解的情況以及哪裏會影響語句的執行,但沒有運氣..LEFT JOIN聲明與ON和WHERE

我有這樣的說法,給了我預期的結果:

 SELECT DISTINCT u1.email 
    FROM user u1 
    LEFT JOIN user u2 
    ON u1.email = u2.email 
    WHERE u1.id != u2.id 

Correct output

轉乘ON和WHERE給出了相同的結果這是很好的,但是當我刪除了在那裏我得到更多的結果是:

SELECT DISTINCT u1.email 
    FROM user u1 
    LEFT JOIN user u2 
    ON u1.email = u2.email 
    AND u1.id != u2.id 

Incorrect output

這是爲什麼?

+0

在結果中添加'u2.email'會讓你更清楚地知道你得到的結果:http://sqlfiddle.com/#!2/6a133/52'LEFT JOIN'也返回那些在'ON'子句中有空匹配 –

+1

@MichaelBerkowski謝謝我明白了! :) – user2868631

回答

1

發生這種情況是因爲在第一種情況下where子句在之後應用並且將刪除僅由「外部」連接包含的所有行。刪除這些行是因爲u2表中的email列對於這些行將爲空,並且與null的任何比較產生未定義,這意味着where子句將放棄這些行。

A where在外連接表上的條件基本上將外連接重新轉換回內連接。

0

對於初學者,您的sqlfiddle與本頁面上的代碼不符。小問題雖然。

簡短的回答是:當你添加一個檢查左連接標準的where子句時,它基本上使它像內連接一樣工作。

0

因爲這是一個LEFT JOIN,你會得到來自u1值和空值的行從u2如果ON條款不成立。但是,WHERE子句適用於整個結果集,因此如果u2.id結果爲NULL,則不會返回。

LEFT JOIN更改爲INNER JOIN將解決您的問題。

0

做左加入並從右表中選擇沒有意義。 如果您使用左連接並應用JOIN子句中的所有條件,則可能會看到意外的結果。 WHERE是在JOIN結果之後應用過濾器,因此除非您的JOIN是INNER,否則JOIN和Where之間的切換條件不相同。 JOIN將提供更多結果。 但如果JOIN是INNER JOIN,那麼無論你的條件是什麼,你都會得到相同的結果。

在你的例子中,如果你只是刪除你在哪裏選擇所有不同的電子郵件,但從u2。因爲你已經離開了連接soem的非匹配的u2行將不會被過濾,因爲它們將與WHERE子句一樣。

+0

這是一個自我加入,所以我不知道左撇子和右撇子有很大的不同。 –

+1

您使用的是同一個表,但連接類型仍然是LEFT OUTER JOIN。口頭上,當我們說selef加入它表明只有一個表參與這個連接,但什麼類型的連接仍然取決於你試圖達到什麼目的。 –