暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

第三章 关系数据库标准语言SQL(4)——数据查询之连接查询

凯哥的故事 2020-05-06
794


连接查询



前面的查询都是针对一个表进行的。若一个查询同时涉及两个以上的表,则称之为连接查询。连接查询是关系数据库中最主要的查询,包括等值连接查询自然连接查询非等值连接查询自身连接查询外连接查询复合条件连接查询等。

①等值与非等值连接查询

连接查询的WHERE子句中用来连接两个表的条件称为连接条件或连接谓词,其一般格式为

[<表名1>.]<列名1><比较运算符>[<表名2>.]<列名2>

其中比较运算符主要有=、>、<、>=、<=、!=(或<>)等。

此外连接谓词还可以使用下面形式:

[<表名1>.]<列名1>BETWEEN [<表名2>.]<列名2>AND [<表名2>.]<列名3>

当连接运算符为=时,称为等值连接。使用其他运算符称为非等值连接

连接谓词中的列名称为连接字段。连接条件中的各连接字段类型必须是可比的,但名字不必相同。

例1】查询每个学生及其选修课程的情况。

学生情况存放在Student表中,学生选课情况存放在SC表中,所以本查询实际上涉及Student与SC两个表。这两个表之间的联系是通过公共属性Sno实现的。

SELECT Student.*,SC.*

FROM Student,SC

WHERE Student.Sno=SC.Sno;

假设Student表、SC表的数据如学生-课程数据库所示,该查询的执行结果如下图所示。

本例中,SELECT子句与WHERE子句中的属性名前都加上了表名前缀,这是为了避免混淆。如果属性名在参加连接的各表中是唯一的,则可以省略表名前缀。

关系数据库管理系统执行该连接操作的一种可能过程是:首先在表Student中找到第一个元组,然后从头开始扫描SC表,逐一查找与Student第一个元组的Sno相等的SC元组,找到后就将Student中的第一个元组与该元组拼接起来,形成结果表中一个元组。SC全部查找完后,再找Student中第二个元组,然后再从头开始扫描SC,逐一查找满足连接条件的元组,找到后就将Student中的第二个元组与该元组拼接起来,形成结果表中一个元组。重复上述操作,直到Student中的全部元组都处理完毕为止。这就是嵌套循环连接算法的基本思想。如下图所示。

如果在SC表Sno上建立了索引的话,就不用每次全表扫描SC表了,而是根据Sno值通过索引找到相应的SC元组。用索引查询SC中满足条件的元组一般会比全表扫描快。

若在等值连接中把目标列中重复的属性列去掉则为自然连接。

例2】对例1用自然连接完成。

SELECT Student.Sno, Sname, Ssex, Sage, Sdept, Cno, Grade

FROM Student,SC

WHERE Student.Sno=SC.Sno;

本例中,由于Sname,Ssex,Sage,Sdept,Cno和Grade属性列在Student表与SC表中是唯一的,因此引用时可以去掉表名前缀;而Sno在两个表都出现了,因此引用时必须加上表名前缀。

一条SQL语句可以同时完成选择和连接查询,这时WHERE子句是由连接谓词和选择谓词组成的复合条件

例3】查询选修2号课程且成绩在90分以上的所有学生的学号和姓名。

SELECT Student.Sno,Sname

FROM Student,SC

WHERE Student.Sno=SC.Sno AND SC.Cno='2' AND SC.Grade>90;

该查询的一种优化(高效)的执行过程是,先从SC中挑选出Cno=2'并且Grade>90的元组形成一个中间关系,再和Student中满足连接条件的元组进行连接得到最终的结果关系。

②自身连接

连接操作不仅可以在两个表之间进行,也可以是一个表与其自己进行连接,称为表的自身连接。

例4】查询每一门课的间接先修课(即先修课的先修课)。

在Course表中只有每门课的直接先修课信息,而没有先修课的先修课。要得到这个信息,必须先对一门课找到其先修课,再按此先修课的课程号查找它的先修课程。这就要将Course表与其自身连接。

为此,要为Course表取两个别名,一个是FIRST,另一个是SECOND。

完成该查询的SQL语句为

③外连接

在通常的连接操作中,只有满足连接条件的元组才能作为结果输出。如例1的结果表中没有201215123和201215125两个学生的信息,原因在于他们没有选课,在SC表中没有相应的元组,导致Student中这些元组在连接时被舍弃了。

有时想以Student表为主体列出每个学生的基本情况及其选课情况。若某个学生没有选课,仍把Student的悬浮元组保存在结果关系中,而在SC表的属性上填空值NULL,这时就需要使用外连接。外连接的概念已经在第二章中讲解过。可以参照例5改写例1。

例5

左外连接列出左边关系(如本例Student)中所有的元组,右外连接列出右边关系中所有的元组。

④多表连接

连接操作除了可以是两表连接、一个表与其自身连接外,还可以是两个以上的表进行连接,后者通常称为多表连接。

例6】查询每个学生的学号、姓名、选修的课程名及成绩。

本查询涉及三个表,完成该查询的SQL语句如下:

SELECT Student.Sno, Sname, Cname, Grade

FROM Student, SC, Course

WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno;

关系数据库管理系统在执行多表连接时,通常是先进行两个表的连接操作,再将其连接结果与第三个表进行连接。本例的一种可能的执行方式是,先将Student表与SC表进行连接,得到每个学生的学号、姓名、所选课程号和相应的成绩,然后再将其与Course表进行连接,得到最终结果。


文章转载自凯哥的故事,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论