对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章(实在不清楚为什么Coding Horror也被墙)通过 文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。

假设我们有两张表。

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会产生什么样的结果。

SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name

id name id name
-- ---- -- ----
1 Pirate 2 Pirate
3 Ninja 4 NinjaInner join
产生的结果集中,是A和B的交集。

Venn diagram of SQL inner 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 VaderFull outer join 产生A和B的并集。但是需要注意的是,对于没有匹配的记录,则会以null做为值。

Venn diagram of SQL cartesian 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 nullLeft outer join 产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代。

Venn diagram of SQL left join

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表中没有的集合。

join-left-outer.png

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表都没有出现的数据集。

join-outer.png
还需要注册的是我们还有一个是“交差集” cross join, 这种Join没有办法用文式图表示,因为其就是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。表达式如下:
复制代码 代码如下:
SELECT * FROM TableA
CROSS JOIN TableB

这个笛卡尔乘积会产生 4 x 4 = 16 条记录,一般来说,我们很少用到这个语法。但是我们得小心,如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然再做过滤。这是对于性能来说是非常危险的,尤其是表很大的时候。

更多相关文章

  1. SQL Server之JSON 函数详解
  2. MySQL 5.7.9 服务无法启动-“NET HELPMSG 3534”的解决方法
  3. MySQL系列多表连接查询92及99语法示例详解教程
  4. Linux下MYSQL 5.7 找回root密码的问题(亲测可用)
  5. MySQL 什么时候使用INNER JOIN 或 LEFT JOIN
  6. Pycharm安装PyQt5的详细教程
  7. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  8. android用户界面之按钮(Button)教程实例汇
  9. 【Android(安卓)开发教程】Toast通知

随机推荐

  1. Android VNC Server on G1 (PC 远程控制
  2. Android开发之android命令大全
  3. Theme.NoTitleBar问题
  4. 自定义android RadioButton样式
  5. Android 检测更新库
  6. android noTouch 事件
  7. 使用SDK Manager更新时出现问题
  8. Android(安卓)仿今日头条频道管理(上)(GridV
  9. 杂谈:后台进程对Android性能的影响
  10. Android手机震动抖动效果的实现