連接查詢是 SQL 核心。本文以 orders(訂單)與 customers(客戶)為例,系統梳理 7 大連接類型、語法差異、結果集差異與選型決策樹。
笛卡爾積,無 ON 條件。隱式(舊語法)與顯式結果相同:
-- 隱式
SELECT o.id, o.order_number, c.id, c.name
FROM orders o, customers c
WHERE o.id = 1;
-- 顯式
SELECT o.id, o.order_number, c.id, c.name
FROM orders o CROSS JOIN customers c
WHERE o.id = 1;
⚠ 極少直接使用,通常作為其他連接的理論基礎。
僅回傳符合連接條件的列。隱式/顯式語法:
-- 隱式
SELECT o.id, o.order_number, c.id, c.name
FROM customers c, orders o
WHERE c.id = o.customer_id;
-- 顯式(推薦)
SELECT o.id, o.order_number, c.id, c.name
FROM customers c INNER JOIN orders o ON c.id = o.customer_id;
顯式語法將「連接條件」與「過濾條件」分離,可讀性高、易維護。
保留一方(或雙方)不符合條件的列,缺補 NULL。
| 類型 | 關鍵字 | 保留方 | 結果行數下限 |
|---|---|---|---|
| 左外連接 | LEFT [OUTER] JOIN | 左表 | 左表行數 |
| 右外連接 | RIGHT [OUTER] JOIN | 右表 | 右表行數 |
| 全外連接 | FULL [OUTER] JOIN | 雙表 | MAX(左,右) |
-- 左外:所有訂單,無客戶資訊則 NULL
SELECT o.id, o.order_number, c.id, c.name
FROM orders o LEFT JOIN customers c ON c.id = o.customer_id;
-- 右外:所有客戶,無訂單則 NULL
SELECT o.id, o.order_number, c.id, c.name
FROM orders o RIGHT JOIN customers c ON c.id = o.customer_id;
-- 全外:MySQL 不支援,可用 UNION 模擬
SELECT ... FROM orders o LEFT JOIN customers c ON ...
UNION
SELECT ... FROM orders o RIGHT JOIN customers c ON ...;
-- 情況 A:WHERE 過濾中間表(正確)
SELECT * FROM orders o LEFT JOIN customers c ON c.id = o.customer_id
WHERE o.order_number <> 'mike_order001';
-- 情況 B:條件寫在 ON 後(語意改變!)
SELECT * FROM orders o LEFT JOIN customers c ON c.id = o.customer_id
AND o.order_number <> 'mike_order001';
情況 B 會導致「不符合條件的訂單」仍被保留(客戶欄位為 NULL),而非過濾掉。**鐵律:ON 只寫連接條件,WHERE 寫業務過濾。**
自動比對同名欄位,無需 ON,不建議生產使用(欄位更名即破壞邏輯)。
極罕見,回傳「全外連接減去內連接」的差異列。Oracle/MySQL 不支援,可用 FULL JOIN ... EXCEPT INNER JOIN ... 模擬。
| 業務場景 | 推薦連接 |
|---|---|
| 只需雙方都有的資料(交集) | INNER JOIN |
| 左表為主,右表補充資訊(右表可能無對應) | LEFT JOIN |
| 右表為主,左表補充 | RIGHT JOIN |
| 雙方都要保留,缺補 NULL | FULL JOIN |
| 找出差異(對帳、稽核) | FULL JOIN + WHERE key IS NULL |
SELECT t1.c1, t2.cx, t3.cy
FROM tab1 t1
INNER JOIN tab2 t2 ON t1.c1 = t2.c2
INNER JOIN tab3 t3 ON t1.c1 = t3.c3
LEFT JOIN tab4 t4 ON t2.c2 = t4.c3
WHERE t1.x > t3.y;
多表混合連接時,**建議先寫核心 INNER JOIN 鏈,再 LEFT JOIN 附屬表**,順序影響執行計畫,必要時用括號或 Hint 強制順序。