關聯式資料庫遵循 第三正規化 (3NF),將資料拆分至多張表以消除冗餘。查詢時需透過 JOIN 依邏輯關聯重組資料。正確選擇 JOIN 類型,關係查詢正確性與效能。
FROM A JOIN B ON A.id = B.id — 關聯條件與篩選條件分離,可讀性高、易維護。FROM A, B WHERE A.id = B.id — 舊式語法,僅支援內聯接,易造成笛卡爾積錯誤。只回傳雙邊皆符合關聯條件的資料列。
SELECT A.symbol, A.sname, B.tdate, B.close
FROM SecurityCode A
INNER JOIN DayQuote B ON A.symbol = B.symbol
WHERE B.tdate >= A.listdate AND A.symbol LIKE '600%';
⚡ INNER 關鍵字可省略,JOIN 預設即為內聯接。
回傳左表所有列,右表無對應則為 NULL。最常用於「主表帶明細」查詢。
SELECT C.cust_name, O.order_id, O.order_date
FROM Customer C
LEFT JOIN Orders O ON C.cust_id = O.cust_id;
左外聯接的鏡像,回傳右表所有列。實務上較少用,通常改寫為左外聯接並交換表順序。
回傳雙邊所有列,無對應處以 NULL 填補。等同 LEFT JOIN UNION RIGHT JOIN 去重。適用於雙向差異比對(如:對帳)。
產生笛卡爾積:左表每列 × 右表每列。極少直接使用,除非需產生測試資料組合或矩陣運算。
-- 3 列 × 4 列 = 12 列結果
SELECT * FROM TableA CROSS JOIN TableB;
INNER JOIN : 交集 (A ∩ B) LEFT JOIN : A 全集 + 交集 RIGHT JOIN : B 全集 + 交集 FULL JOIN : A ∪ B (聯集) CROSS JOIN : A × B (笛卡爾積)
優化器會自動重排,但建議:先篩選小結果集、再聯接大表。使用 CTE 或衍生表預先過濾。
-- 情境:找出所有客戶及其 2023 年訂單
-- ✅ 正確:ON 中篩選右表,左表保留
SELECT C.*, O.*
FROM Customer C
LEFT JOIN Orders O ON C.id = O.cust_id AND O.order_date >= '2023-01-01';
-- ❌ 錯誤:WHERE 篩選右表欄位,會將外聯接隱性轉為內聯接
SELECT C.*, O.*
FROM Customer C
LEFT JOIN Orders O ON C.id = O.cust_id
WHERE O.order_date >= '2023-01-01'; -- 無訂單客戶被過濾掉
-- 員工與主管姓名對照
SELECT E.emp_name AS Employee, M.emp_name AS Manager
FROM Employee E
LEFT JOIN Employee M ON E.mgr_id = M.emp_id;
ON YEAR(A.dt) = YEAR(B.dt)),導致索引失效。| 需求 | 建議 JOIN | 關鍵字 |
|---|---|---|
| 只需雙方都有資料 | 內聯接 | JOIN / INNER JOIN |
| 主表全保留,明細可能無 | 左外聯接 | LEFT JOIN |
| 明細全保留,主表可能無 | 右外聯接 | RIGHT JOIN |
| 雙向全保留,差異比對 | 完整外聯接 | FULL JOIN |
| 產生所有組合 | 交叉聯接 | CROSS JOIN |
JOIN 是 SQL 查詢的核心技能。掌握五大類型語意差異、ON/WHERE 放置陷阱、索引配合策略,能寫出正確、高效、可維護的查詢語句。