首頁 >資料庫 >mysql教程 >為什麼在 WHERE 子句中過濾右側欄位時,LEFT JOIN 會變成 INNER JOIN?

為什麼在 WHERE 子句中過濾右側欄位時,LEFT JOIN 會變成 INNER JOIN?

DDD
DDD原創
2024-12-29 14:47:11745瀏覽

Why Does a LEFT JOIN Become an INNER JOIN When Filtering on a Right-Side Column in the WHERE Clause?

左連接行為問題:使用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 值的行。

解決方案
  1. 要解決此行為並恢復預期的左連接,有兩個選項:
AND (c.foobar = 'somethingelse' OR c.foobar IS NULL)
修改WHERE子句:

  1. 此新增允許包含 tableThree 中的 NULL 值,保留左連接行為。
LEFT JOIN tableThree AS c ON b.pk = c.fk
AND c.foobar = 'somethingelse'
移動到Join 謂詞:

透過移動c.foobar條件放入連接謂詞中,查詢明確指定連接內所需的過濾條件,確保僅連接匹配的行。

以上是為什麼在 WHERE 子句中過濾右側欄位時,LEFT JOIN 會變成 INNER JOIN?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn