SQL Server连接查询笔记

连接查询是关系型数据库的主要特点,也是区别于其他类型数据库的一个标志。

连接查询概念:根据两个表或多个表的列之间的关系,从这些表中查询数据。

连接查询目的:实现多表联合查询操作。

举例

现在有两张数据库表,第一张图片为student表,第二张图为class表,他们之间通过class_id这个字段可以联系起来。

连接查询语法:

1
FROM  join_table join_type join_table[ON (join_condition)]

其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一个表操作的连接又称做自连接。join_type 指出连接类型。join_condition指连接条件。

连接分为三种类型,分别是:内连接外连接交叉连接

内连接

使用比较运算符(包括=、>、<、<>、>=、<=、!>和!<)进行表间的比较操作,查询与连接条件相匹配的数据。根据比较运算符不同,内连接分为等值连接不等连接自然连接三种。

1.等值连接

概念:在连接条件中使用等于号(=)运算符,其查询结果中列出被连接表中的所有列,包括其中的重复列。

1
2
3
4
5
6
7
8
9
SELECT
a.class_id,
a.class_name,
b.student_name
FROM
class AS a
INNER JOIN student AS b
on
a.class_id= b.class_id

执行结果为:

可以看到,查询结果只列出了class_id相对应(相等)的行。一般情况下好像用等值连接比较多。

2.不等连接

概念:在连接条件中使用除等于号之外运算符(>、<、<>、>=、<=、!>和!<)

1
2
3
4
5
6
7
8
9
SELECT
a.class_id,
a.class_name,
b.student_name
FROM
class AS a
INNER JOIN student AS b
on
a.class_id<> b.class_id

执行结果为:

将所有不符合条件的都列了出来。

3.自然连接

概念:自然连接是特殊的等值连接,要求两个关系中进行比较的分量必须是同名的属性组,并且在结果中把重复的属性列去掉。

但是经过查询貌似SQL Server不支持自然连接。

外连接

外连接分为左连接(LEFT JOIN)或左外连接(LEFT OUTER JOIN)、右连接(RIGHT JOIN)或右外连接(RIGHT OUTER JOIN)、全连接(FULL JOIN)或全外连接(FULL OUTER JOIN)。我们就简单的叫:左连接、右连接和全连接。

1.左连接

概念:返回左表中的所有行,如果左表中行在右表中没有匹配行,则结果中右表中的列返回空值。

1
2
3
4
5
6
7
8
9
SELECT
a.class_id,
a.class_name,
b.student_name
FROM
class AS a
LEFT JOIN student AS b
on
a.class_id= b.class_id

执行结果为:

可以看到,这里用左连接查询显示了所有的班级,但是在学生表中找不到班级id为4的学生, 所以三班的学生名字字段显示为空。

总结:左连接显示左表全部行,和右表与左表相同行。

2.右连接

概念:恰与左连接相反,返回右表中的所有行,如果右表中行在左表中没有匹配行,则结果中左表中的列返回空值。

1
2
3
4
5
6
7
8
9
SELECT
b.class_id,
a.class_name,
b.student_name
FROM
class AS a
RIGHT JOIN student AS b
on
a.class_id= b.class_id

执行结果为:

可以看到,这里列出了所有学生的班级id,但是由于在班级表中没有id为4的班级,所以学生王五的班级名为空。 总结:右连接恰与左连接相反,显示右表全部行,和左表与右表相同行。

3.全连接

概念:返回左表和右表中的所有行。当某行在另一表中没有匹配行,则另一表中的列返回空值

1
2
3
4
5
6
7
8
9
10
SELECT
a.class_id,
a.class_name,
b.class_id,
b.student_name
FROM
class AS a
full JOIN student AS b
on
a.class_id= b.class_id

执行结果为:

可以看到,这里显示出了所有的班级和所有的学生。由于没有学生是三班的,所有id为4的班级学生名字这一列为空。由于没有id为3的班级,所有班级id为3的学生对应的班级名字列为空。

总结:返回左表和右表中的所有行。

交叉连接

概念:交叉连接(CROSS JOIN)也称迪卡尔积,不带WHERE条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积(例如:student和class,返回3*3=9条记录),如果带where,返回或显示的是匹配的行数。

1.不带where字句的情况

1
2
3
4
5
6
SELECT
*
FROM
class AS a
CROSS JOIN student AS b
-- 不带where字句的情况

执行结果为:

可以看到这里一共返回了9条数据,将左表和右表每条数据都对应的生成了一行数据。

总结:相当与笛卡尔积,左表和右表组合。

2.带where字句的情况

1
2
3
4
5
6
7
8
SELECT
*
FROM
class AS a
CROSS JOIN student AS b
WHERE
a.class_id= b.class_id
-- 带where字句的情况

执行结果为:

可以看到这里返回的数据和等值连接是一样的,但是有where字句的情况下往往会先生成两个表的乘积条数据,在根据where字句来筛选数据,在数据量比较大的时候可能会很慢。

UNION和UNION ALL

在数据库中,UNION和UNION ALL都是讲两个结果集合并为一个,但是两者从使用和效率上来说有所不同

UNION

union在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。

union all

union all只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。

从效率上说,union all要比union快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用union all。

使用 union 组合查询的结果集有两个最基本的规则

1.所有查询中的列数和列的顺序必须相同。

2.数据类型必须兼容

注意:使用UNION命令时需要注意,只能在最后使用一个ORDER BY命令,是将两个查询结果合在一起之后,再进行排序!绝对不能写两个ORDER BY命令。

参考连接:

https://blog.csdn.net/jiuqiyuliang/article/details/10474221

https://www.cnblogs.com/qiantuwuliang/archive/2009/05/31/1492778.html

https://www.runoob.com/sql/sql-union.html

本文章首发于个人博客 LLLibra146’s blog
本文作者:LLLibra146
版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!
本文链接https://blog.d77.xyz/archives/509db9e6.html