SQL - 连接关系 - 内连接,左连接,右连接,全连接

之前虽然一直在用连接语法,但是从来没有系统的总结过,今天抽空总结一下。

先准备下面讲解过程中需要用到的两张表,这两张表尽可能的简单,能让大家理解。

user 表:

id	name	age
1	Allen	16
2	June	18
3	Jhon	28
4	Amy	45
5	Jack	67

order 表:

id	user_id	order_no	create_time
1	1	00001	2018-07-03 16:37:15
2	3	00002	2018-07-03 16:39:16
3	5	00003	2018-07-03 16:39:24
4	7	00004	2018-07-03 16:39:32
5	9	00005	2018-07-03 16:39:40

1. 内连接

内连接是根据连接条件,取多个表相互匹配的所有行。 简单来理解就是多个表在连接条件上的交集。 

它有两种写法,隐式写法(反而是我们最常用的写法):

SELECT A.*, B.order_no, B.create_time FROM `user` A, `order` B WHERE A.id=B.user_id;
id	name	age	order_no	create_time
1	Allen	16	00001	2018-07-03 16:37:15
3	Jhon	28	00002	2018-07-03 16:39:16
5	Jack	67	00003	2018-07-03 16:39:24

结果中返回了 user 表 id 与 order 表 user_id 相匹配的所有行。其他行不显示。

还有一种显示写法 (Inner Join)

SELECT A.*, B.order_no, B.create_time FROM `user` AS A INNER JOIN `order` AS B ON A.id=B.user_id;

2. 左外连接

左外连接是显示左表的所有行,右表只显示匹配连接条件的行,在右表中没有匹配的行中,选择列字段值为null。

结果行数为左表查询出的行数。

SELECT A.*, B.id AS order_id, B.create_time FROM `user` AS A LEFT JOIN `order` AS B ON A.id=B.user_id;
name	age	order_id	create_time
Allen	16	1	2018-07-03 16:37:15
Jhon	28	2	2018-07-03 16:39:16
Jack	67	3	2018-07-03 16:39:24
June	18		
Amy	45		

3. 右外连接

右外连接是显示右表中的所有行,左表只显示匹配连接条件的行,在左表中没有匹配的行中,选择列字段值为null。

正好与左连接相反,结果行数为右表查询出的行数。

SELECT A.*, B.id AS order_id, B.create_time FROM `user` AS A RIGHT JOIN `order` AS B ON A.id=B.user_id;
id	name	age	order_id	create_time
1	Allen	16	1	2018-07-03 16:37:15
3	Jhon	28	2	2018-07-03 16:39:16
5	Jack	67	3	2018-07-03 16:39:24
			4	2018-07-03 16:39:32
			5	2018-07-03 16:39:40

4. 全外连接

全外连接其实就是返回左连接和右连接中的所有行。表之间的匹配行为基表,当一个表中的某行在另一个表中没有匹配行时,则另一个表中的选择列在连接到该行时为值null。

SELECT A.*, B.order_no, B.create_time FROM `user` AS A FULL JOIN `order` AS B ON A.id=B.user_id;

幸,Mysql不支持全连接(FULL JOIN),这句话我并没有测试。

但是可以通过另外一种办法来实现全连接(UNION):

SELECT A.*, B.order_no, B.create_time FROM `user` AS A LEFT JOIN `order` AS B ON A.id=B.user_id
UNION 
SELECT A.*, B.order_no, B.create_time FROM `user` AS A RIGHT JOIN `order` AS B ON A.id=B.user_id;
id	name	age	order_no	create_time
1	Allen	16	00001	2018-07-03 16:37:15
3	Jhon	28	00002	2018-07-03 16:39:16
5	Jack	67	00003	2018-07-03 16:39:24
2	June	18		
4	Amy	45		
			00004	2018-07-03 16:39:32
			00005	2018-07-03 16:39:40
用过 union 语法将左连接和右连接的结果合并,即获得了全连接的结果。

全外连接实际是上左外连接和右外连接的数学合集(去掉重复),即“全外=左外 UNION 右外”。

5. where 与 on 后面的条件

我们来先看一个例子:

SELECT A.*, B.order_no, B.create_time FROM `user` AS A LEFT JOIN `order` AS B ON A.id=B.user_id WHERE A.age > 18;
id	name	age	order_no	create_time
3	Jhon	28	00002	2018-07-03 16:39:16
5	Jack	67	00003	2018-07-03 16:39:24
4	Amy	45		

若我们将上一个SQL语句中 where 后面的条件放到 on 后面:

SELECT A.*, B.order_no, B.create_time FROM `user` AS A LEFT JOIN `order` AS B ON A.id=B.user_id AND A.age > 18;
id	name	age	order_no	create_time
3	Jhon	28	00002	2018-07-03 16:39:16
5	Jack	67	00003	2018-07-03 16:39:24
1	Allen	16		
2	June	18		
4	Amy	45		

结果不一样!结果不一样!结果不一样!第1个语句返回的结果是可以理解的,第二个结果完全无法去理解,虽然执行不会报错。因此,我们在写SQL语句的是要要注意了。

一般我们会遵循以下规则:

1. on 后面只跟连接条件。

2. 对于中间表的筛选条件放在 where 后面。

先写到这里,后面会补充 SQL 连接的原理:笛卡尔积

可以先参考这篇文章 SQL的多表查询(笛卡尔积原理)



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值