左連接行為問題:使用WHERE 子句轉換為內連接
考慮以下SQL 語句:
SELECT a.foo b.bar c.foobar FROM tableOne AS a INNER JOIN tableTwo AS b ON a.pk = b.fk LEFT JOIN tableThree AS c ON b.pk = c.fk WHERE a.foo = 'something' AND c.foobar = 'somethingelse'
考慮以下SQL 語句:
在這種情況下,期望的是左連結行為。然而,觀察到的行為是,左側連接似乎根據 AND c.foobar = 'somethingelse' 子句的存在而轉換為內連接。 tableThree 中缺少對應 'somethingelse' 值的行不會被傳回。
理解行為關鍵點在於 WHERE 子句與 LEFT JOIN 之間的交互作用。當在 WHERE 子句中從左側聯接的右側指定非 NULL 值時,NULL 值將會被消除,從而有效地將聯接轉換為內聯。 在這種情況下,AND c. foobar = 'somethingelse' 子句過濾掉 tableThree 中 foobar 為 NULL 的行。這表示只傳回 tableTwo 和 tableThree 中具有符合非 NULL 值的行。
解決方案AND (c.foobar = 'somethingelse' OR c.foobar IS NULL)修改WHERE子句:
LEFT JOIN tableThree AS c ON b.pk = c.fk AND c.foobar = 'somethingelse'移動到Join 謂詞:透過移動c.foobar條件放入連接謂詞中,查詢明確指定連接內所需的過濾條件,確保僅連接匹配的行。
以上是為什麼在 WHERE 子句中過濾右側欄位時,LEFT JOIN 會變成 INNER JOIN?的詳細內容。更多資訊請關注PHP中文網其他相關文章!