JOIN查詢中,條件放在ON還是WHERE,對LEFT JOIN與INNER JOIN產生截然不同的結果。本文通過具體資料集與多條對比語句,徹底釐清這一核心知識點。
| 表 a (id, type) | |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 表 b (id, class) | |
|---|---|
| 1 | 1 |
| 2 | 2 |
SELECT a.*, b.* FROM a LEFT JOIN b ON a.id = b.id AND a.type = 1;
結果:左表全部3行保留,右表匹配行顯示,不匹配行為NULL
| a.id | a.type | b.id | b.class |
|---|---|---|---|
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
| 3 | 2 | NULL | NULL |
結論:LEFT JOIN中,左表條件放在ON不影響左表行輸出,只影響右表匹配。
SELECT a.*, b.* FROM a LEFT JOIN b ON a.id = b.id WHERE a.type = 1;
結果:左表先JOIN再過濾,僅保留type=1的2行
| a.id | a.type | b.id | b.class |
|---|---|---|---|
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
結論:WHERE在JOIN後過濾,會過濾掉左表不符合條件的行,實際轉為內連接行為。
SELECT a.*, b.* FROM a LEFT JOIN b ON a.id = b.id AND b.class = 1;
結果:右表條件在ON中生效,過濾右表匹配行
| a.id | a.type | b.id | b.class |
|---|---|---|---|
| 1 | 1 | 1 | 1 |
| 2 | 1 | NULL | NULL |
| 3 | 2 | NULL | NULL |
結論:右表條件放在ON會限制右表參與匹配的行,左表仍全保留。
語句4-7四種寫法(ON帶條件、WHERE帶條件、舊式逗號連接+WHERE、條件順序調換)結果完全一致:
| a.id | a.type | b.id | b.class |
|---|---|---|---|
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
核心規則:INNER JOIN中,ON與WHERE條件最終效果相同,僅執行計畫可能差異(現代優化器通常能統一)。
理解這一機制,能避免因條件位置錯誤導致的資料缺失或效能退化,是SQL進階的必修課。