连接查询是关系数据库中最主要的查询,包括等值连接查询、自然连接查询、非等值连接查询、自身连接查询、外连接查询和复合条件连接查询等。
一、等值与非等值连接查询
连接查询的WHERE子句中用来连接两个表的条件称为连接条件或连接谓词,其一般格式为:
[<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2> ,其中比较运算符主要有:=,>,<,>=,<=,!=(或<>)等。此外,连接谓词还可以使用下面形式[<表名1>.] <列名1> BETWEEN [<表名2>.] <列名2> AND [<表名2>.] <列名3>。
当连接运算符为=时,称为等值连接。使用其他运算符称为非等值连接。连接谓词中的列名称为连接字段。连接条件中的各连接字段类型必须是可比的,但名字不必相同。
SELECT Student.*,SC.* FROM Student,SC WHERE Student.Sno=SC.Sno
RDBMS执行该连接操作的一种可能过程是:
首先在表Student中找到第一个元祖,然后从头开始扫描SC表,逐一查找与Student第一个元组的Sno相等的SC元组,找到后就将Student中的第一个元组与该元组拼接起来,形成结果表中的一个元组。SC全部查找完后,再找Student中第二个元组,然后再从头扫描SC,逐一查找满足连接条件的元组,找到后就将Student中的第二个元组与该元组拼接起来,形成结果表中的一个元组。重复上述操作,直到Student中的全部元组都处理完毕为止。这就是嵌套循环算法的基本思想。
如果在SC表Sno上建立了索引的话,就不用每次全表扫描SC表了,而是根据Sno值通过索引找到对应的SC元组。用索引查询SC中满足条件的元组一般会比全表扫描快。
(1)若在等值连接中把目标列中重复的属性值去掉则为自然连接。
(2)自身连接
二、外连接
在通常的连接操作中,只有满足条件的元组才能作为结果输出。左外连接列出左边关系中所有的元组,右外连接列出右边关系中所有的元组。
三、复合条件连接
WHERE 子句中可以有多个连接条件,称为复合条件连接。
查询选修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中满足连接条件的元组进行连接得到最终的结果关系。
连接操作除了可以是两表连接,一个表与其自身连接外,还可以是两个以上的表进行连接,后者通常称为多表连接。
四、嵌套查询
在SQL语言中,一个SELECT-FROM-WHERE 语句称为一个查询块。将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询。
eg:
SELECT Sname FROM Student WHERE Sno IN (SELECT Sno FROM SC WHERE Cno='2')
上层的查询块称为外层查询或福查询,下层查询块称为内层查询或子查询。SQL语言允许多层嵌套查询。即一个子查询中还可以嵌套其他子查询。需要特别指出的是,子查询的SELECT语句中不能使用ORDER BY 子句,ORDER BY 子句只能对最终查询结果排序。
1、带有IN谓词的子查询
在嵌套查询中,子查询的结果往往是一个集合,所以谓词IN是嵌套查询中最经常使用的谓词。
eg:SELECT Sno,Sname,Sdept FROM Student WHERE Sdept IN (SELECT Sdept FROM Student WHERE Sname='张三');本例中,子查询的查询条件不依赖与父查询,称为不相关子查询。一种求解方法是由里向外处理,即先执行子查询,子查询的结果用于建立其父查询的查找条件。
2、带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户能确切知道内层查询返回的是单值时,可以用>,<,=,>=,<=,!=或<>等比较运算符。
找出每个学生超过他所选修课程平均成绩的课程号
SELECT Sno,Cno FROM SC x WHERE Grade >= (SELECT AVG(Grade) FROM SC y WHERE y.Sno=x.Sno)
x是表SC的别名,又称为元组变量,可以用来表示SC的一个元组。内层查询是求一个学生所有选修课程平均成绩的,至于是哪个学生的平均成绩要看参数x.Sno的值,而该值是与父查询相关的,因此这类查询称为相关子查询。
这个语句的一种可能的执行过程是:
1、从外层查询中取出SC的一个元组x,将元组x的Sno值传送给内层查询。
2、执行内层查询,得到值,用该值代替内层查询,得到外层查询
3、执行这个查询,得到结果。