数据库原理-数据查询 连接查询

110 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情

数据库原理-数据查询 连接查询

不像关系代数中“连接”是用一个特殊符号来表达的,在SQL中“连接”是用“连接条件”来表达的。

连接条件或连接谓词:用来连接两个表的条件

一般格式:

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

连接字段:连接谓词中的列名称

  • 连接条件中的各连接字段类型必须是可比的,但名字不必相同

等值与非等值连接查询

等值连接:连接运算符为“=”

查询每个学生及其选修课程的情况

	SELECT Student.*,SC.*
	FROM Student,SC
	WHERE Student.Son=sc.Sno

image-20220501162106641

自然连接

采用在SELECT中去掉重复字段的方法实施

	SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
	FROM Student,SC
	WHERE Student.Sno=SC.Sno

连接操作的执行过程

嵌套循环法(NESTED-LOOP)

  • 首先在表1中找到第一个元组,然后从头开始扫描表2,逐一查询满足连接条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中的一个元组
  • 表2全部查询完后,再找表1中第二元组,然后再从头开始扫描表2,逐一查询满足连接条件的元组,找到后就将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组
  • 重复上述操作,直到表1中的全部元组都处理完毕

排序合并法(SORT-MERGE)

  • 常用于等值连接
  • 首先按连接属性对表1和表2排序
  • 设置指针,分别指向表1和表2的第一个元组。如果这两个元组满足连接条件,则进行元组拼接(如果有多个连接元组满足连接条件,则需要一一拼接),并将两指针分别后移一个元组。否则,将具有较小值的指针后移一个元组
  • 重复上述操作,直到表1或表2中的全部元组都处理完毕为止

索引连接(INDEX-JOIN)

  • 对表2按连接字段建立索引
  • 对表1中的每个元组,依次根据其连接字段值查询表2的索引,从中找到满足条件的元组,找到后将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组
  • (该方法可以视作嵌套循环法的一个变种)

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

	SELECT Student.Sno,Sname
	FROM Student,SC
	WHERE Student.son=SC.Sno AND
		  SC.Cno='2' AND SC.Grade>90;

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

自身连接

自身连接:一个表与其自己进行连接,是一种特殊的连接

需要给表起别名以示区别

由于所有属性名都是同名属性,因此必须使用别名前缀

查询每一门课的直接先修课的名称

	SELECT FIRST.Cname, SECOND.Cname
	FROM Course FIRST, Course SECOND
	WHERE FIRST.Cpno = SECOND.Cno;

image-20220501165245501

image-20220501165309587

外连接

外连接与普通连接的区别

  • 普通连接操作只输出满足连接条件的元组
  • 外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出
  • 左外连接
    • 列出左边关系中所有的元组
  • 右外连接
    • 列出右边关系中所有的元组

查询每个学生及其选修课程的情况

	SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
	FROM Student LEFT OUTER JOIN SC ON
		 (Student.Son=SC.Sno)

有些商业系统的表达更简单:

	SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
	FROM Student,SC
	WHERE Student.Sno (+)=SC.Sno

image-20220501170731937

多表连接

多表连接:两个以上的表进行连接

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

	SELECT Student.Sno,Sname,Cname,Grade
	FROM Student,SC,Course
	WHERE Student,Sno = SC.Sno
		  AND SC.Cno = Course.Cno;