最近写SQL写得比较多,碰巧看到了Coding Horror上的一篇文章,很有趣,所以转过来备份~

简单粗暴一张大图

link_wxeWKE6sWYzRjJ1afyGW48OgWep2cZL3,w1200h627.jpg

详解

假设我们有两张表。

  • 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的交集。 6a0120a85dcdae970b012877702708970c-pi.png

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做为值。 6a0120a85dcdae970b012877702725970c-pi.png

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

6a0120a85dcdae970b01287770273e970c-pi.png

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表中没有的集合。 6a0120a85dcdae970b012877702754970c-pi.png

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表都没有出现的数据集 6a0120a85dcdae970b012877702769970c-pi.png

CROSS JOIN

这种JOIN没有办法用Venn图表示,但是我们可以用这张图来表示,蹬蹬蹬~ venn-cross-join1.png

但是如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然后再做过滤,所以cross join这种方法会使SQL性能受到很大影响,所以一般公司里的SQL都会禁用CROSS JOIN方法。