了解JOIN 查詢中WHERE 和ON 子句的差異
連接兩個表Foo 和Bar 時,請考慮以下場景:他們的BarId 欄位:
INNER JOIN with WHERE子句
SELECT * FROM Foo f INNER JOIN Bar b ON b.BarId = f.BarId WHERE b.IsApproved = 1;
INNER JOIN with ON 子句
SELECT * FROM Foo f INNER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
這兩個查詢傳回相同的結果。然而,在處理外連接時,出現了一個關鍵的差異。讓我們來探索如何使用LEFT OUTER JOIN:
帶有ON 子句過濾器的LEFT OUTER JOIN
SELECT * FROM Foo f LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
帶有WHERE 子句過濾器的LEFT OUTER JOIN
SELECT * FROM Foo f LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId) WHERE (b.IsApproved = 1);
在第一個查詢,在連接過程中根據 IsApproved 列過濾右表 (Bar) 中的行。相反,在第二個查詢中,此過濾是在 連接之後執行的。
當 b.BarId 為空值時,這種差異變得很重要。在第一個查詢中,此類行仍將包含在結果中(Bar 中的列為空值)。在第二個查詢中,這些行將會被 WHERE 子句過濾掉。
OPTIONAL 過濾器的等價
對於 OPTIONAL 過濾器(例如,b.IsApproved 不是限制),帶有 WHERE 子句的等效 LEFT OUTER JOIN將be:
SELECT * FROM Foo f LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId) WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
這既考慮了聯接失敗的情況(b.BarId 為 null,應該忽略過濾器),也考慮了聯接成功並且應該應用過濾器的情況。
結論
雖然乍一看似乎在WHERE 或ON 子句中放置過濾器儘管無關緊要,但行為上的細微差別(尤其是對於外部連接而言)需要仔細考慮。這種區別確保了準確的資料檢索和高效的查詢優化。
以上是JOIN 子句中的 WHERE 與 ON:過濾器放置何時重要?的詳細內容。更多資訊請關注PHP中文網其他相關文章!