當需要跨多個資料表整合資料時,選擇正確的 SQL 語法至關重要。本文系統說明合併多表查詢的三大主流方式:隱含 JOIN、標準 JOIN (INNER/OUTER/CROSS) 與子查詢,並分析各自優缺點與適用場景。
本文範例遵循 SQL-92 ISO 標準。實務上各資料庫廠商 (Oracle、SQL Server、MySQL、PostgreSQL 等) 實作細節可能不同,請參考對應文件確認支援度。
在 FROM 子句列出多個資料表,於 WHERE 子句指定連接條件:
SELECT table1.column1, table2.column2
FROM table1, table2
WHERE table1.column1 = table2.column1;
table1.column1 明確指定欄位來自哪張表,提升可讀性並避免歧義SELECT table1.column1, table2.column2
FROM table1, table2, table3
WHERE table1.column1 = table2.column1
AND table1.column1 = table3.column1;
亦可僅利用第三表過濾結果而不輸出其欄位。
WHERE 遺漏連接條件,將產生笛卡兒積 (CROSS JOIN) 導致結果爆增明確指定連接類型,提供更精確的結果控制與潛在效能優勢。
| 類型 | 行為說明 |
|---|---|
| INNER JOIN | 僅回傳雙邊皆有配對資料的列 (等同隱含 JOIN) |
| LEFT OUTER JOIN | 回傳左表所有列,右表無配對則為 NULL |
| RIGHT OUTER JOIN | 回傳右表所有列,左表無配對則為 NULL |
| FULL OUTER JOIN | 回傳雙邊所有列,無配對處填 NULL |
| CROSS JOIN | 笛卡兒積,所有排列組合 |
SELECT table1.column1, table2.column2
FROM table1
INNER JOIN table2
ON table1.column1 = table2.column1;
優勢:連接條件與過濾條件分離 (ON vs WHERE),語意更清晰;複雜多表查詢時優化器通常能產生更好執行計畫。
將一個 SELECT 陳述式巢狀置入另一個查詢中,作為資料來源或過濾條件。
SELECT column1 FROM table1
WHERE EXISTS (
SELECT column1 FROM table2
WHERE table1.column1 = table2.column1
);
IN / NOT IN:檢查值是否存在於子查詢結果集中EXISTS / NOT EXISTS:檢查子查詢是否回傳至少一列 (通常效能優於 IN)相關子查詢:子查詢參考外層查詢的欄位,逐列評估子查詢便利但有代價:每個子查詢會先完整執行再供外層使用。對大量資料或複雜邏輯,改寫為 JOIN 常能大幅降低延遲。建議:
| 情境 | 建議方式 | 理由 |
|---|---|---|
| 雙表簡單等值連接 | 隱含 JOIN 或 INNER JOIN | 語法簡潔,效能相近 |
| 需保留單邊所有資料 | LEFT/RIGHT OUTER JOIN | 語意明確,隱含 JOIN 難表達 |
| 三表以上複雜關聯 | 標準 JOIN | 可讀性、維護性、優化器友善 |
| 單純存在性檢查 | EXISTS 子查詢 | 語意清楚,通常比 IN 快 |
| 動態計算欄位作為過濾條件 | 子查詢或 CTE | 邏輯封裝性佳 |