萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

SQL JOIN 深度解析:LEFT JOIN 中 ON 與 WHERE 條件位置的關鍵差異

核心結論

  • INNER JOIN:ON 與 WHERE 條件效果等價,僅影響可讀性。
  • LEFT / RIGHT JOIN:ON 條件決定「如何關聯」,WHERE 條件決定「最終保留哪些行」。位置不同,結果天差地別。

測試資料

Table A (id, type)          Table B (id, class)
1, 1                        1, 1
2, 1                        2, 2
3, 2

三條 LEFT JOIN 對比

1. 條件在 ON(左表過濾)

SELECT a.*, b.* FROM a LEFT JOIN b ON a.id = b.id AND a.type = 1;
結果:左表 3 行全保留,a.type=2 的行右表欄位為 NULL。
a.id a.type b.id b.class
1    1      1    1
2    1      2    2
3    2      NULL NULL

2. 條件在 WHERE(左表過濾)

SELECT a.*, b.* FROM a LEFT JOIN b ON a.id = b.id WHERE a.type = 1;
結果:先 LEFT JOIN 產生中間表(3 行),再用 WHERE 過濾 → 僅保留 a.type=1 的 2 行。
a.id a.type b.id b.class
1    1      1    1
2    1      2    2

3. 條件在 ON(右表過濾)

SELECT a.*, b.* FROM a LEFT JOIN b ON a.id = b.id AND b.class = 1;
結果:左表全保留,右表僅保留 class=1 的行,其餘置 NULL。
a.id a.type b.id b.class
1    1      1    1
2    1      NULL NULL
3    2      NULL NULL

INNER JOIN 驗證

-- 以下四句結果完全相同
SELECT * FROM a INNER JOIN b ON a.id = b.id AND a.type = 1;
SELECT * FROM a INNER JOIN b ON a.id = b.id WHERE a.type = 1;
SELECT * FROM a, b WHERE a.id = b.id AND a.type = 1;
SELECT * FROM a, b WHERE a.type = 1 AND a.id = b.id;

結果均為 2 行(a.type=1 且關聯成功)。

實務建議

  1. 關聯條件寫在 ON:a.id = b.id、b.status = 1 等「如何關聯」的規則。
  2. 業務過濾寫在 WHERE:a.type = 1、a.create_time > '2023-01-01' 等「要哪些資料」的規則。
  3. 若需「左表全保留、右表依條件關聯」,右表條件必須寫在 ON。
  4. 避免在 LEFT JOIN 的 ON 中放左表過濾條件(除非刻意要保留左表所有行)。

總結

ON 是關聯邏輯,WHERE 是結果過濾。外連接時,二者位置決定「保留哪一方的不匹配行」。內連接則無差異。掌握此規則,可精準控制 JOIN 結果集,避免資料遺漏或多出。

copyright © 萬盛學電腦網 all rights reserved