萬盛學電腦網

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

MySQL LEFT JOIN WHERE 多表條件陷阱與多表聯查詳解

MySQL 左連接搭配 WHERE 條件時,常會踩到「條件寫在 ON vs WHERE 結果不同」的坑。本文透過實例解析差異,並完整補充內連接、左連接、右連接、全連接的行為差異。

核心陷阱:WHERE 條件會將 LEFT JOIN 隱性轉為 INNER JOIN

錯誤寫法:條件直接寫在 WHERE

SELECT * FROM _test a 
LEFT JOIN _test b ON a.id = b.id 
WHERE a.level = '20' AND a.month = '04' 
  AND b.level = '20' AND b.month = '03';

因為右表 b 的條件寫在 WHERE,若右表無匹配行,b.level 為 NULL,條件不成立,導致左表資料也被過濾掉,實際變成內連接。

正確寫法:右表條件寫在 ON 或用子查詢預過濾

SELECT a.*, b.* 
FROM (SELECT * FROM _test WHERE level = '20' AND month = '04') AS a
LEFT JOIN (SELECT * FROM _test WHERE level = '20' AND month = '03') AS b
ON a.id = b.id;

子查詢先過濾,再做左連接,才能保留左表所有符合條件的資料,右表無匹配時顯示 NULL。

四種聯查類型完整對照

假設兩表:

T1 (userid, username, password)
1, jack, jackpwd
2, owen, owenpwd

T2 (userid, jifen, dengji)
1, 20, 3
3, 50, 6

1. INNER JOIN(內連接)

SELECT * FROM T1 INNER JOIN T2 ON T1.userid = T2.userid;

結果:僅保留雙方都有的 userid=1。

2. LEFT OUTER JOIN(左連接)

SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.userid = T2.userid;

結果:T1 全部保留,T2 無匹配處為 NULL(userid=2 的 owen 保留)。

3. RIGHT OUTER JOIN(右連接)

SELECT * FROM T1 RIGHT OUTER JOIN T2 ON T1.userid = T2.userid;

結果:T2 全部保留,T1 無匹配處為 NULL(userid=3 的行保留)。

4. FULL OUTER JOIN(全連接)

SELECT * FROM T1 FULL OUTER JOIN T2 ON T1.userid = T2.userid;

結果:左右表全部保留,去重合併(MySQL 不直接支援,可用 UNION 模擬)。

效能與最佳實踐

  • INNER JOIN 效率最高,優先使用
  • 左/右連接時,右表的過濾條件務必寫在 ON 子句,不要寫在 WHERE
  • 複雜多表查詢建議用 CTE(WITH 子句)或子查詢預先過濾
  • 靈活運用四種連接方式,能大幅簡化複雜 SQL 結構
copyright © 萬盛學電腦網 all rights reserved