多表查詢有三種主流語法:隱性 JOIN (WHERE 關聯)、顯性 JOIN (JOIN ... ON)、子查詢 (Subquery)。本文依 SQL-92 標準詳細對比三者語法、行為差異、效能特性與適用場景,助你選對工具。
1. 隱性 JOIN (舊式逗號語法)
SELECT t1.c1, t2.c2 FROM table1 t1, table2 t2
WHERE t1.c1 = t2.c1;
- 相當於 INNER JOIN。
- 多表以逗號分隔,關聯條件寫在 WHERE。
- 優點:簡短、直觀。缺點:易漏寫 WHERE 導致笛卡兒積;混合外部聯接語法 (`*=`/`=*`) 已棄用;優化器處理複雜時不如顯性 JOIN 穩定。
- 可擴展多表:
WHERE t1.c1=t2.c1 AND t1.c1=t3.c1。
- 可引用不輸出的表作為過濾:
FROM t1, t2, t3 WHERE t1.c1=t2.c1 AND t1.c1=t3.c1 (t3 僅過濾)。
2. 顯性 JOIN (ANSI SQL-92 標準)
SELECT t1.c1, t2.c2 FROM t1 INNER JOIN t2 ON t1.c1 = t2.c1;
- 類型:INNER / LEFT / RIGHT / FULL OUTER / CROSS。
- 優點:關聯條件與過濾條件分離、外部聯接語意明確、複雜多表優化器規劃更佳、可讀性強。
- LEFT JOIN 保留左表所有列;RIGHT JOIN 保留右表;FULL 保留雙邊。
3. 子查詢 (Subquery / 衍生表)
SELECT c1 FROM t1 WHERE EXISTS (SELECT c1 FROM t2 WHERE t1.c1 = t2.c1);
- 用途:限制結果集、定義衍生表、SELECT 列回傳純量。
EXISTS 通常優於 IN (尤其子查詢大、外層小)。
- 效能代價:子查詢獨立完整執行後再供外層使用;大數據量下不如 JOIN 高效。創造性改寫為 JOIN 常能大幅降低延遲。
選擇決策樹
- 需外部聯接 (保留不匹配) → 顯性 LEFT/RIGHT/FULL JOIN。
- 單純內部聯接、表數少 (≤3)、邏輯簡單 → 隱性 JOIN 可接受。
- 表數多、關聯複雜、需外部聯接、團隊協作 → 強制顯性 JOIN。
- 子查詢用於「存在性檢查」或「衍生表」且無法輕易改寫 JOIN 時使用;大量資料優先嘗試改寫為 JOIN。
廠商差異提醒
並非所有資料庫完整支援 SQL-92;Oracle 早期版本外部聯接用 `(+)`,SQL Server 早期用 `*=`/`=*`,現代版本均支援標準語法。生產環境請以目標資料庫文件為準。