如何理解SQL里的Join操作

表和表之间的联接,即join操作是SQL里很重要的操作之一。理解了联接,就能有效地关联关系型数据。

Join操作一共分为3种:

1. 交叉联接

这是所有联接中最基础也是必须执行的第一个步骤,SQL语法称为cross join

假设A表有m条数据,m = 2

AId Name
1 Red
2 Blue

B表有n条数据,n = 2

BId RGB
2 00FF00
3 FFFF00

那么A表和B表进行交叉连接后,一共会产生m * n条,本例为4条数据。

AId Name BId RGB
1 Red 2 00FF00
1 Red 3 FFFF00
2 Blue 2 00FF00
2 Blue 3 FFFF00

这就是我们常说的笛卡尔积。要联接的两表的行数越多,笛卡尔积的结果集也就越大。

2. 内联接

交叉联接将所有的组合可能性都考虑到了,并汇集到了一个结果集里。内联接就是操作这个结果集,筛选出满足联接条件的行。SQL语法称为inner join

假设前面的例子,要筛选出满足A表的AId等于B表的BId的行,SQL写法为

1
2
3
4
select A.*, B.*
from A
inner join B
on A.AId = B.BId

这里的A.AId = B.BId就是联接条件,当有联接条件时必须加上on谓词。如果还有其它联接条件只要用and连接即可。结果为

AId Name BId RGB
2 Blue 2 00FF00

换句话说,内联接就是起过滤行的作用,过滤的对象是满足过滤条件的由交叉连接产生的结果集。

3. 左(右)联接

左联接比起内联接来,区别只多出了一个步骤,在内联接的基础之上补充左表被内联接过滤掉的那些行,右表的行的数据以NULL替代。什么意思,用上面的例子来解释,A表左联接B表,筛选条件为AId = BId,SQL写法为

1
2
3
4
select A.*, B.*
from A
left join B
on A.AId = B.BId

结果

AId Name BId RGB
2 Blue 2 00FF00
1 Red NULL NULL

A(左)表AId为1的行,原本是不满足过滤条件的,也就是被内联接过滤掉的行,但是左联接会将左表被内联接过滤掉的行,添加到结果集的最后,右表的数据则用NULL替代

换句话说,左表会返回所有行,不满足联接条件的右表返回NULL。

右联接(right join)以及全联接(full join)原理同左联接。

总结

为什么我要写下这篇文章,因为工作的时候,使用左联接查询,以为返回的结果集行数就应该等于左表的行数。后来才发现我忘了交叉连接的存在,如果联接条件是一对多的话,左联接产生的结果集行数大于左表的行数。也是提醒自己,不要忘了交叉联接的存在,它是所有联接的基础。

为什么我要写这篇文章,原因是因为一开始理解左联接的时候,容易被左表返回所有行

avatar

chilihotpot

You Are The JavaScript In My HTML