一、外連接(OUTER JOIN)
- 左外連接(左邊的表不加限制)
- 右外連接(右邊的表不加限制)
- 全外連接(左右兩表都不加限制)
對應SQL:LEFT/RIGHT/FULL OUTER JOIN。 通常省略OUTER關鍵字, 寫成:LEFT/RIGHT/FULL JOIN。
在左連接和右連接時都會以一張A表為基礎表,該表的內容會全部顯示,然后加上A表和B表匹配的內容。 如果A表的數據在B表中沒有記錄。 那么在相關聯的結果集行中列顯示為空值(NULL)。即A表中的數據全部顯示,無論其where條件是否匹配,即使不匹配其不匹配的數據用null來填充。
對於外連接, 也可以使用“(+) ”來表示。關於使用(+)的一些注意事項:
- (+)操作符只能出現在WHERE子句中,並且不能與OUTER JOIN語法同時使用。
- 當使用(+)操作符執行外連接時,如果在WHERE子句中包含有多個條件,則必須在所有條件中都包含(+)操作符。
- (+)操作符只適用於列,而不能用在表達式上。
- (+)操作符不能與OR和IN操作符一起使用。
- (+)操作符只能用於實現左外連接和右外連接,而不能用於實現完全外連接。
即:(+)相當於省略LEFT/RIGHT/FULL OUTER JOIN.......ON這種繁雜的語句
二、創建兩個表用於測試
CREATE TABLE t_A ( id number, name VARCHAR2(10) ); CREATE TABLE t_B ( id number, name VARCHAR2(10) ); INSERT INTO t_A VALUES(1,'A'); INSERT INTO t_A VALUES(2,'B'); INSERT INTO t_A VALUES(3,'C'); INSERT INTO t_A VALUES(4,'D'); INSERT INTO t_A VALUES(5,'E'); INSERT INTO t_B VALUES(1,'AA'); INSERT INTO t_B VALUES(1,'BB'); INSERT INTO t_B VALUES(2,'CC'); INSERT INTO t_B VALUES(1,'DD');
圖1
三、左連接(LEFT OUTER JOIN/ LEFT JOIN)
LEFT JOIN是以左表的記錄為基礎的,示例中t_A可以看成左表,t_B可以看成右表,它的結果集是t_A表中的全部數據,再加上t_A表和t_B表匹配后的數據。換句話說,左表(t_A)的記錄將會全部表示出來,而右表(t_B)只會顯示符合搜索條件的記錄。t_B表記錄不足的地方均為NULL。
對應SQL語句:
select * from t_A a left join t_B b on a.id = b.id;
或
select * from t_A a left outer join t_B b on a.id = b.id;
圖2
用(+)來實現, 這個+號可以這樣來理解: + 表示補充,即哪個表有加號,這個表就是匹配表。如果加號寫在右表,左表就是全部顯示,所以是左連接。
對應SQL語句:
Select * from t_A a,t_B b where a.id=b.id(+);
圖3
三、右連接(RIGHT OUTER JOIN/ RIGHT JOIN)
和LEFT JOIN的結果剛好相反,是以右表(t_B)為基礎的。它的結果集是t_B表所有記錄,再加上t_A和t_B匹配后的數據。 t_A表記錄不足的地方均為NULL。
對應SQL語句:
select * from t_A a right join t_B b on a.id = b.id;
或
select * from t_A a right outer join t_B b on a.id = b.id;
圖4
用(+)來實現, 這個+號可以這樣來理解: + 表示補充,即哪個表有加號,這個表就是匹配表。如果加號寫在左表,右表就是全部顯示,所以是右連接。
對應SQL語句:
Select * from t_A a,t_B b where a.id(+)=b.id;
圖5
四、全外連接(FULL OUTER JOIN/FULL JOIN)
左表和右表都不做限制,所有的記錄都顯示,兩表不足的地方均為NULL。 全外連接不支持(+)寫法。
對應SQL語句:
select * from t_A a full join t_B b on a.id = b.id;
或
select * from t_A a full outer join t_B b on a.id = b.id;
圖6
五、個人想法
上邊說的太抽象了,例子還可以,建議直接看例子。其實很簡單,對於內連接,就像我們之前寫的那種where a.id = b.id一樣,這種等值連接
就叫做內連接,還有非等值連接比如where a.money >= b.money,都屬於內連接。
我們之前熟悉的寫法叫做內連接,外連接是在內連接的基礎上,再加上了一些東西,而這一些東西,我們接下來說明一下。
我們知道數據庫表的連接實際上就是笛卡爾積,M行的A表與N行的B表進行連接查詢,若不加where條件查到的數據就是MxN行,從A表中的每一條
數據對應B表中的N條數據。加上where條件后,例如A.id = B.id這種條件,將MxN行的笛卡爾積數據結果進行篩選,把不相等的都給去掉,留下相等的數據。
這時A表B表都可以會因為條件的設置失去幾行數據,這是我們常說的內連接。
外連接出現了,對於A表左連接B表,當我們得到MxN行的笛卡爾積的數據集后,這時加入了where條件,我們不能像內連接一樣去掉A表中的數據了,
上文中我們說外連接就是比內連接多了一部分,這一部分就是:為了保證左連接,我們要保存A表中的全部數據,無論是否符合where條件A.id = B.id,即使A
表與B表的兩個id不相等,我們也不能把該列刪除,而是要看查詢的最終視圖中該行的A表數據是否已經存在了,若存在,則該行的笛卡爾積數據不用管,若
不存在,仍要保存A表中的數據,但因為與B表id不匹配,所以將B表的各個列設為null。這樣做保證A表的所有數據都必須存在,這就是左連接,其余類似。
所以我說,外連接就是比內連接多了一點東西——多了即使條件不成立但仍要滿足一表全部顯示的null列。