Oracle左外連線、右外連線、完全外連線以及(+)號用法

weixin_34249678發表於2018-08-31

一、準備工作

oracle連線分為:
左外連線:左表不加限制,保留左表的資料,匹配右表,右表沒有匹配到的行中的列顯示為null。
右外連線:右表不加限制,保留右表的資料。匹配左表,左表沒有匹配到的行中列顯示為null。
完全外連線:左右表都不加限制。即右外連線的結果為:左右表匹配的資料+左表沒有匹配到的資料+右表沒有匹配到的資料。

二、連線的語法

left/right/full outer join ...on
left/right/full join ...on
(+)號的作用:+號可以理解為補充的意思,加在那個表的列上就代表這個表的列為補充。加在右表的列上代表右表為補充,為左連線。加在左表的列上代表左表為補充,為右連線。注意:完全外連線中不能使用+號。

三、測試

  • 準備測試資料
    建立兩種表,插入測試資料:
CREATE TABLE t_A (
id   number,
code   number,
name  VARCHAR2(10)
);
 
CREATE TABLE t_B (
id   number,
code   number,
name  VARCHAR2(10)
);
 
INSERT INTO t_A(id,code,name) VALUES(1,2,'A');
INSERT INTO t_A(id,code,name) VALUES(2,1,'B');
INSERT INTO t_A(id,code,name) VALUES(3,5,'C');
INSERT INTO t_A(id,code,name) VALUES(4,6,'D');
INSERT INTO t_A(id,code,name) VALUES(5,7,'E');
 
INSERT INTO t_B(id,code,name) VALUES(1,3,'AA');
INSERT INTO t_B(id,code,name) VALUES(1,4,'BB');
INSERT INTO t_B(id,code,name) VALUES(2,1,'CC');
INSERT INTO t_B(id,code,name) VALUES(1,2,'DD');
INSERT INTO t_B(id,code,name) VALUES(7,5,'GG');

檢視插入的資料:

select * from t_a;
select * from t_b;
13491695-20207cfcf31bdc17.png
表t_a的資料
13491695-05d97fa082e01fe5.png
表t_b的資料
  • 左外連線
select * from t_a a left join t_b b on a.id=b.id;
select * from t_a a,t_b b where a.id=b.id(+);

執行結果


13491695-32d024bbd74a938b.png
左外連線
  • 右外連線
select * from t_a a right join t_b b on a.id=b.id;
select * from t_a a,t_b b where a.id(+)=b.id;

執行結果


13491695-02438ae5a7de572d.png
右外連線
  • 完全外連線
select * from t_a a full join t_b b on a.id=b.id;
select * from t_a a,t_b b where a.id(+)=b.id(+); --錯誤語法,不支援兩邊(+)

執行結果


13491695-b45accfe26d2c31b.png
完全外連線
  • 等值連線
select * from t_a a,t_b b where a.id=b.id;
select * from t_a a join t_b b on a.id=b.id;--等值連線也可以這樣寫

執行結果


13491695-5236298afc3aeb91.png
等值連線
  • 左外連線(多鍵值)
select * from t_a a left join t_b b on a.id=b.id and a.code=b.code;
select * from t_a a,t_b b where a.id=b.id(+) and a.code=b.code(+);

執行結果


13491695-aa15c30f2dd716d5.png
左外連線(多鍵值)
  • 右外連線(多鍵值)
select * from t_a a right join t_b b on a.id=b.id and a.code=b.code;
select * from t_a a,t_b b where a.id(+)=b.id and a.code(+)=b.code;

執行結果


13491695-bf79f7234ac1dc74.png
右外連線(多鍵值)
  • 完全外連線(多鍵值)
select * from t_a a full join t_b b on a.id=b.id and a.code=b.code;

執行結果


13491695-de0101913650f581.png
完全外連線(多鍵值)
  • 等值連線(多鍵值)
select * from t_a a,t_b b where a.id=b.id and a.code=b.code;
select * from t_a a join t_b b on a.id=b.id and a.code=b.code;--等值連線也可以這樣寫

執行結果


13491695-e297c2600732603d.png
等值連線(多鍵值)
  • 左外連線(多鍵值or)
select * from t_a a left join t_b b on a.id=b.id or a.code=b.code;
select * from t_a a,t_b b where a.id=b.id(+) or a.code=b.code(+); --錯誤:ORA-01719: OR 或 IN 運算元中不允許外部聯接運算子 (+)

執行結果


13491695-80ee0a5ac259db3d.png
左外連線(多鍵值or)
  • 右外連線(多鍵值or)
select * from t_a a right join t_b b on a.id=b.id or a.code=b.code;
select * from t_a a,t_b b where a.id(+)=b.id or a.code(+)=b.code; --錯誤:ORA-01719: OR 或 IN 運算元中不允許外部聯接運算子 (+)

執行結果


13491695-8f946299c8a09c1e.png
右外連線(多鍵值or)
  • 完全外連線(多鍵值or)
select * from t_a a full join t_b b on a.id=b.id or a.code=b.code;

執行結果


13491695-be8da362ef89a105.png
完全外連線(多鍵值or)
  • 等值連線(多鍵值or)
select * from t_a a,t_b b where a.id=b.id or a.code=b.code;
select * from t_a a join t_b b on a.id=b.id or a.code=b.code;--等值連線也可以這樣寫

執行結果


13491695-a2c64e6107c524ed.png
等值連線(多鍵值or)
  • 試試
select * from t_a a,t_b b where a.id=b.id(+) and a.code(+)=b.code;
// 錯誤:ORA-01416: 兩表無法彼此外部連線

select * from t_a a left join t_b b on a.id=b.id where a.code(+)=b.code;
select * from t_a a, t_b c left join t_b b on a.id=b.id where a.code(+)=c.code;
// ORA-25156: 舊樣式的外部聯接 (+) 不能與 ANSI 聯接一起使用

select * from  t_a a 
left join t_b b on a.id=b.id 
left join t_b c on a.id=c.id;

select * from  t_a a,t_b b,t_b c
 where a.id=b.id(+) and a.id=c.id(+);

select * from  t_a a 
left join t_b b on a.id=b.id 
left join t_b c on a.id=c.id and b.id=c.id;

select * from  t_a a,t_b b,t_b c
 where a.id=b.id(+) and a.id=c.id(+) and b.id=c.id(+);
 
select * from  t_a a,t_b b,t_b c
 where a.id=b.id(+) and a.id=c.id(+) and b.id=c.id;
 
select * from  t_a a 
left join t_b b on a.id=b.id 
left join t_b c on a.id=c.id and b.code=c.code;

select * from  t_a a,t_b b,t_b c
 where a.id=b.id(+) and a.id=c.id(+) and b.code=c.code(+);

select * from  t_a a,t_b b,t_b c
 where  b.code=c.code(+) and a.id=b.id(+) and a.id=c.id(+) ;

 select * from  t_a a,t_b b,t_b c
 where  a.id=b.id(+) and a.id=c.id(+)  or a.code=c.code ;
 
  select * from  t_a a,t_b b,t_b c
 where  (a.id=b.id(+) and a.id=c.id(+)) or a.code=c.code ;
 
   select * from  t_a a,t_b b,t_b c
 where a.id=b.id(+) and (a.id=c.id(+) or a.code=c.code) ;

多個連線條件的注意事項

Oracle中,兩個表通過多個關連條件外連線的時候,如果多個條件中有沒有寫(+)的條件,則連線會自動變成內連線,而不再是外連線。這種情況應該是屬於寫SQL的失誤。遇到這種情況的時候一定要注意。

相關文章