Join

過濾條件差異 - Where 子句與加入條件

  • September 6, 2019

快速簡單的過濾問題。

輸出會有什麼差異,或者它將過濾條件從 WHERE 子句移到 Join 條件中會有什麼影響。

例如:

Select a1.Name, a2.State
from student a1
left join location a2 on a1.name_id = a2.name_id
where a1.name LIKE 'A%'
and a2.state = 'New York';

對此:

Select a1.Name, a2.State
from student a1
left join location a2 on (a1.name_id = a2.name_id) and a2.state = 'New York'
where a1.name LIKE 'A%';

謝謝大家。

  1. 將顯示以“A”開頭且位置在紐約的學生姓名。

  2. 將顯示所有以“A”開頭的學生姓名,如果學生所在州是紐約,則顯示“紐約”,或者在其他情況下為空(沒有對應的州,或者學生所在州不是紐約)

(1) 和 (2) 之間的區別 - (1) 不會有非紐約學生。

@a1ex07 的答案是完全正確的。但是,讓我們提供一個更籠統的答案。

當你有一個TableA a LEFT JOIN TableB b場景時,你必須小心你如何在你的子句中使用TableB欄位。WHERE

對於 中TableA沒有匹配行的任何行TableB,所有欄位TableB都將設置為 NULL。

讓我們看看你的例子。

我們假設您希望 ( ) 中的所有行在TableA( student) 中沒有匹配的行,或者TableB在( location)中具有匹配的行,其中( ) 等於“紐約”。TableB``b.Column1``location.State

  1. 如果您的WHERE子句包含對TableB不允許在該欄位中使用 NULL 值的欄位的檢查,則將排除所有TableA沒有匹配行的行。TableB

範例:WHERE b.State = 'New York'-TableA沒有匹配TableB行的行將具有B.Column1NULL。由於NULL = 'New York'不是 TRUE,因此沒有匹配( ) 行的TableA( ) 行都不符合子句中的條件。student``TableB``location``WHERE

實際上,這使得LEFT JOINan INNER JOIN. 2. 如果您確實允許TableB值為 NULL,則需要注意不要允許輸入比您的意思更多的值。

如果將上述範例WHERE子句更改為:

WHERE (b.State = 'New York' OR b.State IS NULL)

然後仍將包括TableA沒有匹配行的行。TableB但是,具有匹配TableA行且設置為 NULL 的行也是如此(在您的情況下,具有匹配行的行,其中為 NULL)。這可能不是本意。TableB``Column1``student``location``location.State 3. 要真正滿足我們假設的意圖,您至少有兩種選擇:

  • 首先,您可以對條件TableB中的行進行限制JOIN
FROM TableA a
       LEFT JOIN TableB b ON (a.name_id = b.name_id AND b.State = 'New York')

允許通過沒有匹配( ) 行的所有`TableA`( ) 行;如果有*匹配*的行,匹配的行來自並且僅當是“紐約”時才會被包括在內。`student``TableB``location``TableB``TableA``TableB``b.State`
其次,在`WHERE`子句中包含您的檢查,但使用`JOIN`in 列`TableB`允許 NULL:
OM TableA a
FT JOIN TableB b ON (a.name_id = b.name_id)
ERE (b.State = 'New York' OR b.name_id IS NULL)

假定`a.name_id`不能為 NULL。然後,唯一的方法`b.name_id`可以是 NULL 是如果沒有找到匹配的`JOIN`in `TableB`。同樣,`TableA`不`TableB`匹配的行也包括在內(因為`b.name_id`這些行總是為 NULL)。根據我們的假設,where`TableA`有一個匹配的`TableB`行,`b.name_id`永遠*不會*是 NULL,因此`b.State` *必須*是“New York”才能包含匹配`TableA`的`TableB`行對。

引用自:https://dba.stackexchange.com/questions/196030