SQL夯实基础(一):inner join、outer join和cross join的区别

一、数据构建

先建表,再说话

create database Test
use Test
create table A
(
AID int identity(1,1) primary key,
name nvarchar(50),
age int
)
create table B
(
BID int identity(1,1) primary key,
name nvarchar(50),
gender  int
)

创建完之后,插入数据

insert A(name,age)values('张三',35)
insert A(name,age)values('李四',25)
insert A(name,age)values('XXX',35)
insert A(name,age)values('YYY',35)

insert B(name,gender)values('张三',1)
insert B(name,gender)values('李四',1)
insert B(name,gender)values('AAA',2)
insert B(name,gender)values('BBB',2)

 

现在建完两张表,Table ATable B其各有四条记录,其中有两条记录name是相同的:

二、对比测试

  缺省情况下是inner join(也就是你直接输入join,开发中使用的left joinright join属于outer join,另外outer join还包括full join.下面我通过图标让大家认识它们的区别。

  这里使用了JOIN…ON子句,用户自己指定一个可以消除笛卡尔积的关联条件。

1.INNER JOIN 产生的结果是AB的交集

SELECT * FROM A INNER JOIN B ON A.name = B.name

 

2.LEFT [OUTER] JOIN 产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代。

SELECT * FROM A LEFT OUTER JOIN B ON A.name = B.name

 

3.RIGHT [OUTER] JOIN 产生表B的完全集,而A表中匹配的则有值,没有匹配的则以null值取代。

SELECT * FROM A RIGHT OUTER JOIN B ON A.name = B.name

 

4.FULL [OUTER] JOIN 产生A和B的并集。对于没有匹配的记录,则会以null做为值。

SELECT * FROM A FULL OUTER JOIN B ON A.name = B.name

 

你可以通过is NULL将没有匹配的值找出来:

SELECT * FROM A FULL OUTER JOIN B ON A.name = B.name
WHERE A.id IS null OR B.id IS null

 

5.CROSS JOIN(交叉连接):用于产生笛卡尔积

  把表A和表B的数据进行一个N*M的组合,即笛卡尔积。如本例会产生4*4=16条记录,在开发过程中我们肯定是要过滤数据,所以这种很少用。

SELECT * FROM A CROSS JOIN B

  相信大家对inner join、outer join和cross join的区别一目了然了。

补充一点:按照sql标准CROSS JOIN是笛卡尔积。但对于mysql来说,CROSS JOIN 相当于 INNER JOIN。

 

 

三、Outer Join 的执行过程

总的来说,outer join 的执行过程分为4步

1、先对两个表执行交叉连接(笛卡尔积)

2、应用on筛选器

3、添加外部行

4、应用where筛选器

第一步,对两个表执行交叉连接,结果如下,这一步会产生36条记录(此图显示不全)

第二步,应用on筛选器。筛选器中有两个条件,main.id = ext.id and address<> '杭州',符合要求的记录如下。

 

这似乎正是我们期望中查询的结果,然而在接下来的步骤中这个结果会被打乱。

第三步,添加外部行。outer join有一个特点就是以一侧的表为基,假如另一侧的表没有符合on筛选条件的记录,则以null替代。在这次的查询中,这一步的作用就是将那条原本应该被过滤掉的记录给添加了回来

 

是不是不种画蛇添足的感觉, 结果就成了这样

 

第四步,应用where筛选器

在这条问题sql中,因为没有where筛选器,所以上一步的结果就是最终的结果了。

而对于那条地址筛选在where条件中的sql,这一步便起到了作用,将所有地址不属于杭州的记录筛选了出来

 

通过上面的讲解,已经能反应出在outer join中的筛选条件在on中和where中的区别,开发人员如能详细了解之中差别,能规避很多在编写sql过程中出现的莫名其妙的错误。

 

 

原文地址:https://www.cnblogs.com/qixinbo/p/8313088.html