最近写SQL写得比较多,碰巧看到了Coding Horror上的一篇文章,很有趣,所以转过来备份~
简单粗暴一张大图
详解
假设我们有两张表。
- Table A 是左边的表。
- Table B 是右边的表。
其各有四条记录,其中有两条记录是相同的,如下所示:
id name id name
-- ---- -- ----
1 Pirate 1 Rutabaga
2 Monkey 2 Pirate
3 Ninja 3 Darth Vader
4 Spaghetti 4 Ninja
对于这两张表而言,不同的JOIN,我们可以用不同的Venn图来表示。
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
Inner join 产生的结果集中,是A和B的交集。
FULL OUTER JOIN
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
Full outer join 产生A和B的并集。但是需要注意的是,对于没有匹配的记录,则会以null做为值。
LEFT OUTER JOIN
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
LEFT OUTER JOIN + IS NULL
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表中没有的集合。
FULL OUTER JOIN + A IS NULL + B IS NULL
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
产生A表和B表都没有出现的数据集
CROSS JOIN
这种JOIN没有办法用Venn图表示,但是我们可以用这张图来表示,蹬蹬蹬~
但是如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然后再做过滤,所以cross join这种方法会使SQL性能受到很大影响,所以一般公司里的SQL都会禁用CROSS JOIN方法。