Oracle 多表連接查詢是 SQL 核心技能。本文系統梳理 Oracle 8i 專有語法((+))與 ANSI SQL:1999 標準語法(INNER/LEFT/RIGHT/FULL JOIN)的對應關係,並通過實例詳細演示各類連接的結果差異。
CREATE TABLE test1 (a INT, b INT);
CREATE TABLE test2 (a INT, b INT);
INSERT INTO test1 VALUES (1, 456);
INSERT INTO test1 VALUES (2, 427);
INSERT INTO test2 VALUES (1, 45456);
INSERT INTO test2 VALUES (3, 45656);
表 A(test1)與表 B(test2)僅在 a=1 時匹配。
(+) 表示外連接)| 連接類型 | 語法 | 結果說明 |
|---|---|---|
| 內連接 | SELECT * FROM test1 a, test2 b WHERE a.a = b.a; | 僅返回匹配行(a=1) |
| 左連接 | SELECT * FROM test1 a, test2 b WHERE a.a = b.a(+); | 返回 test1 所有行,test2 無匹配則為 NULL |
| 右連接 | SELECT * FROM test1 a, test2 b WHERE a.a(+) = b.a; | 返回 test2 所有行,test1 無匹配則為 NULL |
| 全連接 | SELECT * FROM test1 a, test2 b WHERE a.a = b.a(+) UNION SELECT * FROM test1 a, test2 b WHERE a.a(+) = b.a; | 8i 無直接語法,需 UNION 實現 |
| 笛卡爾積 | SELECT * FROM test1, test2; | 無連接條件,行數相乘 |
-- 內連接
SELECT * FROM A INNER JOIN B ON A.ID = B.ID;
-- 左外連接
SELECT * FROM A LEFT JOIN B ON A.ID = B.ID;
-- 等同於 LEFT OUTER JOIN
-- 右外連接
SELECT * FROM A RIGHT JOIN B ON A.ID = B.ID;
-- 全外連接
SELECT * FROM A FULL OUTER JOIN B ON A.ID = B.ID;
| A.ID | A.NAME | B.ID | B.CLASS |
|---|---|---|---|
| 1 | IBM | 1 | C1 |
| 2 | SONY | 3 | C3 |
| 3 | BMW | 4 | C4 |
ID NAME CLASS
1 IBM C1
3 BMW C3
僅返回雙方都存在的匹配行。
ID NAME CLASS
1 IBM C1
2 SONY NULL
3 BMW C3
保留左表(A)所有行,右表無匹配填 NULL。
ID NAME CLASS
1 IBM C1
3 BMW C3
4 NULL C4
保留右表(B)所有行,左表無匹配填 NULL。
ID NAME CLASS
1 IBM C1
2 SONY NULL
3 BMW C3
4 NULL C4
雙邊全保留,無匹配處填 NULL。
(+) 和 JOIN ... ON。LEFT JOIN B ON A.ID = B.ID AND B.TYPE = 'X',而非 WHERE,否則退化為內連接。掌握從 (+) 到標準 JOIN 的演進,不僅能讀懂舊代碼,更能編寫清晰、可維護的現代 SQL。建議新項目全面採用 ANSI JOIN 語法。