對於SQL的Join,在學習起來多是比較亂的。咱們知道,SQL的Join語法有不少inner的,有outer的,有left的,有時候,對 於Select出來的結果集是什麼樣子有點不是很清楚。Coding Horror上有一篇文章,經過文氏圖 Venn diagrams 解釋了SQL的Join。我以爲清楚易懂,轉過來。 性能
假設咱們有兩張表。Table A 是左邊的表。Table B 是右邊的表。其各有四條記錄,其中有兩條記錄name是相同的,以下所示:讓咱們看看不一樣JOIN的不一樣 學習
A表 |
id |
name |
1 |
Pirate |
2 |
Monkey |
3 |
Ninja |
4 |
Spaghetti |
B表 |
id |
name |
1 |
Rutabaga |
2 |
Pirate |
3 |
Darth Vade |
4 |
Ninja |
1. [INNER] JOIN spa
SELECT * FROM TableA INNER JOIN TableB ON TableA.name = TableB.name ci
結果集 |
(TableA.) |
(TableB.) |
id |
name |
id |
name |
1 |
Pirate |
2 |
Pirate |
3 |
Ninja |
4 |
Ninja |
Inner join 產生的結果集中,是A和B的交集。 table
2.FULL [OUTER] JOIN
(1)
SELECT * FROM TableA
FULL OUTER JOIN TableB ON TableA.name = TableB.name
結果集 |
(TableA.) |
(TableB.) |
id |
name |
id |
name |
1 |
Pirate |
2 |
Pirate |
2 |
Monkey |
null |
null |
3 |
Ninja |
4 |
Ninja |
4 |
Spaghetti |
null |
null |
null |
null |
1 |
Rutabaga |
null |
null |
3 |
Darth Vade |
Full outer join 產生A和B的並集。可是須要注意的是,對於沒有匹配的記錄,則會以null作爲值。
可使用IFNULL判斷。
(2)
SELECT * FROM TableA
FULL OUTER JOIN TableB ON TableA.name = TableB.name
WHERE TableA.id IS null OR TableB.id IS null
結果集 |
(TableA.) |
(TableB.) |
id |
name |
id |
name |
2 |
Monkey |
null |
null |
4 |
Spaghetti |
null |
null |
null |
null |
1 |
Rutabaga |
null |
null |
3 |
Darth Vade |
產生A表和B表沒有交集的數據集。
3.LEFT [OUTER] JOIN
(1)
SELECT * FROM TableA
LEFT OUTER JOIN TableB ON TableA.name = TableB.name
結果集 |
(TableA.) |
(TableB.) |
id |
name |
id |
name |
1 |
Pirate |
2 |
Pirate |
2 |
Monkey |
null |
null |
3 |
Ninja |
4 |
Ninja |
4 |
Spaghetti |
null |
null |
Left outer join 產生表A的徹底集,而B表中匹配的則有值,沒有匹配的則以null值取代。
(2)
SELECT * FROM TableA
LEFT OUTER JOIN TableB ON TableA.name = TableB.name
WHERE TableB.id IS null
結果集 |
(TableA.) |
(TableB.) |
id |
name |
id |
name |
2 |
Monkey |
null |
null |
4 |
Spaghetti |
null |
null |
產生在A表中有而在B表中沒有的集合。 基礎
4.RIGHT [OUTER] JOIN
RIGHT OUTER
JOIN 是後面的表爲基礎,與LEFT OUTER JOIN用法相似。這裏不介紹了。
5.UNION 與
UNION ALL
UNION 操做符用於合併兩個或多個 SELECT 語句的結果集。
請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有類似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同。UNION 只選取記錄,而UNION ALL會列出全部記錄。
(1)SELECT name FROM TableA
UNION SELECT name FROM TableB
新結果集 |
name |
Pirate |
Monkey |
Ninja |
Spaghetti |
Rutabaga |
Darth Vade |
選取不一樣值
(2)SELECT name FROM TableA
UNION ALL SELECT name FROM TableB
新結果集 |
name |
Pirate |
Monkey |
Ninja |
Spaghetti |
Rutabaga |
Pirate |
Darth Vade |
Ninja |
所有列出來 select
(3)注意: 數據類型
SELECT * FROM TableA
UNION SELECT * FROM TableB
新結果集 |
id |
name |
1 |
Pirate |
2 |
Monkey |
3 |
Ninja |
4 |
Spaghetti |
1 |
Rutabaga |
2 |
Pirate |
3 |
Darth Vade |
4 |
Ninja |
因爲 id 1 Pirate 與 id 2 Pirate 並不相同,不合並
還須要註冊的是咱們還有一個是「交差集」 cross join, 這種Join沒有辦法用文式圖表示,由於其就是把表A和表B的數據進行一個N*M的組合,即笛卡爾積。表達式以下:SELECT * FROM TableA CROSS JOIN TableB
這個笛卡爾乘積會產生 4 x 4 = 16 條記錄,通常來講,咱們不多用到這個語法。可是咱們得當心,若是不是使用嵌套的select語句,通常系統都會產生笛卡爾乘積然再作過濾。這是對於性能來講是很是危險的,尤爲是表很大的時候。