| 連接類型 | 關鍵字 | 回傳結果說明 |
|---|---|---|
| 內連接 | INNER JOIN | 僅回傳雙方符合連接條件的資料列 |
| 左外部連接 | LEFT [OUTER] JOIN | 左表全部列 + 右表符合條件列(無符合則 NULL) |
| 右外部連接 | RIGHT [OUTER] JOIN | 右表全部列 + 左表符合條件列(無符合則 NULL) |
| 全外部連接 | FULL [OUTER] JOIN | 雙方全部列,無符合處以 NULL 填補 |
| 交叉連接 | CROSS JOIN | 笛卡兒積:左表每列 × 右表每列,無連接條件 |
DECLARE @tbl1 TABLE (id1 CHAR(10), name1 CHAR(10));
INSERT INTO @tbl1 VALUES ('1','a'), ('2','b'), ('33','d'), ('44','e');
DECLARE @tbl2 TABLE (id2 CHAR(10), name2 CHAR(10));
INSERT INTO @tbl2 VALUES ('1','a'), ('2','b'), ('55','d'), ('66','e');
SELECT * FROM @tbl1 AS a INNER JOIN @tbl2 AS b ON a.id1 = b.id2;
結果:僅回傳 id=1、id=2 兩筆匹配資料。
SELECT * FROM @tbl1 AS a LEFT JOIN @tbl2 AS b ON a.id1 = b.id2;
結果:@tbl1 4 筆全保留;id=33,44 在 @tbl2 無對應,name2 顯示 NULL。
SELECT * FROM @tbl1 AS a RIGHT JOIN @tbl2 AS b ON a.id1 = b.id2;
結果:@tbl2 4 筆全保留;id=55,66 在 @tbl1 無對應,name1 顯示 NULL。
SELECT * FROM @tbl1 AS a FULL JOIN @tbl2 AS b ON a.id1 = b.id2;
結果:雙方 4+4=8 筆邏輯列,合併後 6 筆(1、2 合併;33、44、55、66 各自保留)。
SELECT * FROM @tbl1 AS a CROSS JOIN @tbl2 AS b;
結果:4 × 4 = 16 筆,無任何匹配邏輯。
-- 錯誤:將右表條件放在 WHERE,會把 LEFT JOIN 變成 INNER JOIN
SELECT * FROM @tbl1 a LEFT JOIN @tbl2 b ON a.id1 = b.id2 WHERE b.name2 = 'a';
-- 正確:右表過濾條件放在 ON 子句
SELECT * FROM @tbl1 a LEFT JOIN @tbl2 b ON a.id1 = b.id2 AND b.name2 = 'a';
ON:決定如何連接,外部連接時不匹配仍保留主表列(右表欄位變 NULL)。WHERE:決定最終保留哪些列,會過濾掉 NULL 列,導致外部連接失效。SELECT a.*, b.*, c.*
FROM TableA a
LEFT JOIN TableB b ON a.id = b.a_id AND b.status = 1 -- 連接時就過濾
LEFT JOIN TableC c ON a.id = c.a_id
WHERE a.category = 'VIP'; -- 主表過濾放 WHERE
ON/WHERE 效果相同,建議用 ON 表達連接關係。FROM 主表 LEFT JOIN 從表 ON 關聯條件 AND 從表過濾條件 WHERE 主表過濾條件。UNION ALL + 子查詢替代以提升相容性。