假設(shè)我們有下面兩張表。表A在左邊蹬刷,表B在右邊畴博。我們給它們各四條記錄许布。
id name id name
-- ---- -- ----
1 Pirate 1 Rutabaga
2 Monkey 2 Pirate
3 Ninja 3 Darth Vader
4 Spaghetti 4 Ninja
我們用過name字段用幾種不同方式把這些表聯(lián)合起來,看能否得到和那些漂亮的韋恩圖在概念上的匹配绎晃。
內(nèi)聯(lián)合(inner join)
SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name
id name id name
-- ---- -- ----
1 Pirate 2 Pirate
3 Ninja 4 Ninja
全外聯(lián)合(full outer join)
生成表A和表B里的記錄全集,包括兩邊都匹配的記錄庶艾。如果有一邊沒有匹配的袁余,缺失的這一邊為null。(如下圖)
SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
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 Vader
左外聯(lián)合(left outer join)
生成表A的所有記錄咱揍,包括在表B里匹配的記錄颖榜。如果沒有匹配的,右邊將是null煤裙。(如下圖)
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
id name id name
-- ---- -- ----
1 Pirate 2 Pirate
2 Monkey null null
3 Ninja 4 Ninja
4 Spaghetti null null
為了生成只在表A里而不在表B里的記錄集掩完,我們用同樣的左外聯(lián)合,然后用where語句排除我們不想要的記錄硼砰。(如下圖)
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableB.id IS null
id name id name
-- ---- -- ----
2 Monkey null null
4 Spaghetti null null
為了生成對于表A和表B唯一的記錄集且蓬,我們用同樣的全外聯(lián)合,然后用where語句排除兩邊都不想要的記錄题翰。(如下圖)
SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableA.id IS null
OR TableB.id IS null
id name id name
-- ---- -- ----
2 Monkey null null
4 Spaghetti null null
null null 1 Rutabaga
null null 3 Darth Vader
笛卡爾積 (交叉聯(lián)合(cross join))
還有一種笛卡爾積或者交叉聯(lián)合(cross join)恶阴,據(jù)我所知不能用韋恩圖表示:
SELECT * FROM TableA
CROSS JOIN TableB
這個把“所有”聯(lián)接到“所有”,產(chǎn)生4乘4=16行豹障,遠多于原始的集合冯事。如果你學(xué)過數(shù)學(xué),你便知道為什么這個聯(lián)合遇上大型的表很危險血公。
【2013-06-17 更新】下圖由 Moffatt 在 2008 年制作(點擊可查看大圖)昵仅。PS:Jeff Atwood 的文章寫于 2007 年。
https://blog.codinghorror.com/a-visual-explanation-of-sql-joins/