连接查询详解
连接分为三种:内连接、外连接、交叉连接。
- 内连接:等值连接、不等连接
- 外连接:左连接、右连接、全连接
- 交叉连接
内连接(INNER JOIN)
使用比较运算符(包括 =、>、<、<>、>=、<=、!> 和 !<)进行表间的比较操作,查询与连接条件相匹配的数据。根据比较运算符不同,内连接分为等值连接和不等连接两种。
1、等值连接
概念:在连接条件中使用等于号(=)运算符,其查询结果中列出被连接表中的所有列,包括其中的重复列。首先把两张表进行笛卡尔连接(也就是交叉连接),然后通过 on 条件去过滤里面的数据,只有 on 条件成立的才会显示。
SELECT *
FROM [学生成绩管理系统].[dbo].[班级信息] as c
Join dbo.学生信息 as s
on c.班级编号 = s.所属班级Code language: JavaScript (javascript)
-- 等同
SELECT *
FROM [dbo].[班级信息] as c, dbo.学生信息 as s
where c.班级编号 = s.所属班级Code language: JavaScript (javascript)
下面三种写法是一样的效果:
SELECT *
FROM [dbo].[学生信息] as s
cross join dbo.班级信息 as c
where s.所属班级 = c.班级编号
GOCode language: JavaScript (javascript)
SELECT *
FROM [学生成绩管理系统].[dbo].[班级信息] as c
Join dbo.学生信息 as s
on c.班级编号 = s.所属班级Code language: JavaScript (javascript)
SELECT *
FROM [dbo].[学生信息] as s, dbo.班级信息 as c
where s.所属班级 = c.班级编号Code language: JavaScript (javascript)
如果有一个学生,它的班级编号在班级表里面不存在(这里需要把外键约束去掉,不建议大家去掉,这里可以约束数据的完整性):
SELECT *
FROM [dbo].[班级信息] as c, dbo.学生信息 as s
where s.姓名 = '王九'Code language: JavaScript (javascript)
SELECT *
FROM dbo.学生信息 as s
Join [dbo].[班级信息] as c
on c.班级编号 = s.所属班级Code language: JavaScript (javascript)
就是因为 on 条件永远都不会成立,所以王九在内连接里面永远都不会出现。
2、不等连接
概念:在连接条件中使用除等于号之外运算符(>、<、<>、>=、<=、!> 和 !<)。
SELECT *
FROM [学生成绩管理系统].[dbo].[班级信息] as c
Join dbo.学生信息 as s
on c.班级编号 > s.所属班级Code language: CSS (css)
-- 等同
SELECT *
FROM [dbo].[班级信息] as c, dbo.学生信息 as s
where c.班级编号 > s.所属班级Code language: JavaScript (javascript)
外连接
外连接分为左连接(LEFT JOIN)或左外连接(LEFT OUTER JOIN)、右连接(RIGHT JOIN)或右外连接(RIGHT OUTER JOIN)、全连接(FULL JOIN)或全外连接(FULL OUTER JOIN)。我们就简单地叫:左连接、右连接和全连接。
1、左连接
概念:返回左表中的所有行,如果左表中行在右表中没有匹配行,则结果中右表中的列返回空值。另外,如果右边表有多条记录和左表的一条记录对应,则左表就出现多条。如果右表匹配不到,则右表用 null 填充;反正左表必须全部记录都存在。正常来说,在内连接的时候,如果 on 的条件不成立,那么是不会显示的,左边的也不会显示。比如下面的王九,但是在左连接中王九也出来了,只不过是右边的用 null。
-- 左外连接
SELECT *
FROM [学生成绩管理系统].[dbo].[班级信息] as c
left Join dbo.学生信息 as s
on c.班级编号 = s.所属班级Code language: JavaScript (javascript)
2、右连接
概念:恰与左连接相反,返回右表中的所有行,如果右表中行在左表中没有匹配行,则结果中左表中的列返回空值。外连接并不是说不允许重复,右连接保证右表都出现,还可以重复。
-- 右外连接
SELECT *
FROM [学生成绩管理系统].[dbo].[班级信息] as c
right Join dbo.学生信息 as s
on c.班级编号 = s.所属班级Code language: JavaScript (javascript)
左连接和右连接其实是一样的,比如下面,右连接完全可以使用左连接去实现:
SELECT *
FROM dbo.学生信息 as s
right join [dbo].[班级信息] as c
on c.班级编号 = s.所属班级Code language: JavaScript (javascript)
SELECT s.*,c.*
FROM [dbo].[班级信息] as c
left join dbo.学生信息 as s
on c.班级编号 = s.所属班级Code language: JavaScript (javascript)
3、全连接
概念:返回左表和右表中的所有行。当某行在另一表中没有匹配行,则另一表中的列返回空值。
SELECT *
FROM [学生成绩管理系统].[dbo].[班级信息] as c
full Join dbo.学生信息 as s
on c.班级编号 = s.所属班级Code language: JavaScript (javascript)
全连接和交叉连接是不一样的。全连接是有 on 条件的,而交叉连接是没有 on 条件的。全连接就是先笛卡尔连接,然后检查 on 条件过滤不符合行,最后再看左表和右表有没有哪些没有出来的。比如上面如果是内连接的话,应该是上面的 19 和 20 行都不符合,但因为是外连接并且是全连接,所以 SQL Server 最后把它们补充到这里。
交叉连接(CROSS JOIN)
也称笛卡儿积。不带 WHERE 条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积(例如:T_student 和 T_class,返回 4 * 4=16 条记录)。如果带 where,返回或显示的是匹配的行数。交叉连接不能有 on,有 on 就报错。
SELECT *
FROM [dbo].[班级信息]
cross Join dbo.学生信息Code language: CSS (css)
-- 另外一种写法
SELECT *
FROM [dbo].[班级信息] , dbo.学生信息Code language: CSS (css)
有 where 子句,往往会先生成两个表行数乘积的数据表,然后才根据 where 条件从中选择。
SELECT *
FROM [dbo].[班级信息] a, dbo.学生信息 b
where a.所属系别 = '200501'Code language: JavaScript (javascript)