mySQL 包含两种联接,分别是内连接 (inner join) 和外连接(out join), 但我们又同时听说过左连接,交叉连接等术语,本文旨在总结这些术语之间的关系。

1. 内连接

首先说明内连接的一个重要性质:内连接查询结果与表的顺序无关
(当然顺序可能会发生变化,但是对应关系绝对不会错乱!!!)

1.1 交叉连接(cross join)

当然,他还有其他的名字,比如:笛卡尔积,交叉积,还有最奇怪的名字 “没有连接”(no join)

使用下列命令同时查询玩具表的 toy 列和男孩表的 boy 列,得到的结果就是交叉连接

SELECT t.toy,b.boy
FROM toys AS t
	CROSS JOIN
	boys AS b;

其中,CROSS JOIN 可以省略,简写为

SELECT t.toy,b.boy
FROM toys AS t,	boys AS b;

交叉连接回把第一张表的每个值与第二张表的每个值进行匹配,结果如下

交叉连接是内连接的一种,你又可以把内连接看作是通过查询中的条件过滤掉某些结果数据行之后的交叉连接。

1.2 相等连接

我们假设每个男孩子都又一个玩具,表之间是一对一的关系,toy_id 是外键,数据库表如下图

我们想找到每个男孩儿拥有什么玩具,只需要将 boys 表中的 toy_id 和 toys 中的主键进行比对,就会得到结果

SELECT boys.boy,toys.toy
FROM boys
	INNER JOIN
	toys
ON boys.toy_id=toys.toy_id;

1.3 不等连接

我们继续沿用 1.2 中的表结构,如果我们想找到每个男孩儿没有的玩具,这时候我们可以使用不等连接(说白了就是 = 换成 <>, 其他没有什么区别)

SELECT boys.boy,toys.toy
FROM boys
	INNER JOIN
	toys
ON boys.toy_id<>toys.toy_id
ORDER BY boys.boy;

1.4 自然连接

继续沿用 1.2 的表结构。。。。。
注意:自然连接只有在连接的列在两张表中的名称都相同时才会有用
其实,自然连接就是自动识别相同列的相等连接

SELECT boys.boy,toys.toy
FROM boys
	NATURAL JOIN
	toys
ORDER BY boys.boy;

得到的结果和 1.2 中的结果完全一样(顺序可能不同)

2. 外连接

首先说明外连接不同于内连接的一个性质:外连接查询与表的顺序有关

2.1 左外连接

LEFT OUTER JOIN(左外连接)接收左表的所有行,并用这些行与右表进行匹配
当左表与右表具有一对多的关系时,左外连接特别有用。我们仍然使用之前的表结构

现在我们利用左外连接找出每个男孩拥有的玩具

SELECT b.boy,t.toy
FROM boys b
LEFT OUTER JOIN toys t
ON b.toy_id=t.toy_id;

LEFT OUTER JOIN 左边的表 boys 我们称为左表,右边的 toys 称为右表,所以 LEFT OUTER JOIN 会取得左表 boys 的所有行和右表的 toys 的行进行匹配,结果如下

我们的查询结果和使用内连接时一样,难道说内连接和外连接没区别吗?怎么可能!!!接下来我们改变一下左表 boys 的表结构

我们向 boys 中新添加了一个 Andy,把他的 toy_id 设置为 6,注意,6 在 toys 表中没有对应的玩具,接下来再次运行上述程序

我们发现居然出现了一个 NULL,NULL 的出现是要告诉我们右表 toys 中没有与左表 boys 中的 Andy 相匹配的行,也就是说

外连接一定会提供数据行,无论还行能否在另一个表中找出相匹配的行

接着做个实验,我们调换左表和右表的顺序

SELECT b.boy,t.toy
FROM toys t
LEFT OUTER JOIN boys b
ON b.toy_id=t.toy_id;

结论:出现 NULL 的列总是右表中的列

以下时左外连接的实际匹配过程

toys 中的玩具 hula hoop 与 boys 中的 Davey 的记录比对,toys.toys_is=1,boys.toy_is=3
不匹配
toys 中的玩具 hula hoop 与 boys 中的 Bobby 的记录比对,toys.toys_is=1,boys.toy_is=5
不匹配
toys 中的玩具 hula hoop 与 boys 中的 Beaver 的记录比对,toys.toys_is=1,boys.toy_is=2
不匹配
toys 中的玩具 hula hoop 与 boys 中的 Richie 的记录比对,toys.toys_is=1,boys.toy_is=1
成功匹配
… 省略 toy_id=2,3 的匹配过程
toys 中的玩具 harmonica 与 boys 中的 Davey 的记录比对,toys.toys_is=4,boys.toy_is=3
不匹配
toys 中的玩具 harmonica 与 boys 中的 Bobby 的记录比对,toys.toys_is=4,boys.toy_is=5
不匹配
toys 中的玩具 harmonica 与 boys 中的 Beaver 的记录比对,toys.toys_is=4,boys.toy_is=2
不匹配
toys 中的玩具 harmonica 与 boys 中的 Richie 的记录比对,toys.toys_is=4,boys.toy_is=1
不匹配
右表查找完毕,没有匹配项,因此创建带有 NULL 值的行来对应 harmonica
… 省略 baseball cards 的匹配过程

2.2 右外连接

与左外连接完全相同,只不过是用右表来评价左表
此外:RIGHT OUTER JOIN 左侧的表为右表!!!!!
这里只简单举一个例子,具体内容参考左外连接

SELECT b.boy,t.toy
FROM toys t
RIGHT OUTER JOIN boys b
ON b.toy_id=t.toy_id;

上述代码等同于

SELECT b.boy,t.toy
FROM boys b
LEFT OUTER JOIN toys t
ON b.toy_id=t.toy_id;

这两种写法都是都把 toys 作为右表,把 boys 作为左表

实验的表结构如下:

结果:

在实际运用过程中,我们一般倾向于只使用一种,另一种简单了解就好。