SELECT(连接查询、嵌套查询)

连接查询

连接查询:同时涉及两个以上的表的查询

连接条件:用来连接两个表的条件

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

【例】 Student.Sno = SC.Sno

连接字段:连接条件中的列名称
如:Sno为上面例子中的连接字段

注意:连接字段类型必须是可比的,但名字不必相同

1.等值与非等值连接查询

等值连接:连接运算符为=
[例 3.49] 查询每个学生及其选修课程的情况

SELECT  Student.*, SC.*
FROM     Student, SC
WHERE  Student.Sno = SC.Sno;

在这里插入图片描述
自然连接:将等值连接中重复的属性列去掉。
[例 3.50] 对[例 3.49]用自然连接完成。

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

在这里插入图片描述
如果你又想去掉你不想看到的数据,又想做连接查询,该怎么办
可以在条件后面增加AND,进行筛选。
[例 3.51 ]查询选修2号课程且成绩在70分以上的所有学生的学号和姓名。

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

在这里插入图片描述
执行过程*:
先从SC中选择出Cno='2’并且Grade>90的元组形成一个中间关系
再和Student中满足连接条件的元组进行连接得到最终的结果关系

2.自身连接

自身连接:一个表与其自己进行连接
自身链接时将需要给表起别名
所有属性名都是同名属性,因此必须使用“别名
[例 3.52]查询每一门课的间接先修课(即先修课的先修课)

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

在这里插入图片描述
在这里插入图片描述

3.外连接

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

[例 3. 53] 改写[例 3.49]
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student LEFT OUT JOIN SC ON (Student.Sno=SC.Sno);
在这里插入图片描述
右连接需要将LEFT换成RIGTH。而全外连接需要改写为FULL

4.多表连接

多表连接:两个以上的表进行连接。
[例3.54]查询每个学生的学号、姓名、选修的课程名及成绩

SELECT Student.Sno, Sname, Cname, Grade
FROM    Student, SC, Course    /*多表连接*/
WHERE Student.Sno = SC.Sno 
              AND SC.Cno = Course.Cno;

在这里插入图片描述

嵌套查询

嵌套查询
一个SELECT-FROM-WHERE语句称为一个查询块
将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询

 SELECT Sname                            /*外层查询/父查询*/
 FROM Student
 WHERE Sno IN
                    ( SELECT Sno        /*内层查询/子查询*/
                      FROM SC
                      WHERE Cno= ' 2 ');

SQL语言允许多层嵌套,但是子查询不能使用ORDER BY子句。

嵌套查询的求解发放
不相关子查询:子查询的查询条件不依赖于父查询
由里向外 逐层处理。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。
相关子查询:子查询的查询条件依赖于父查询
首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表
然后再取外层表的下一个元组
重复这一过程,直至外层表全部检查完为止

1.带有IN谓词的子查询

[例 3.55] 查询与“刘晨”在同一个系学习的学生。
第一种方法:分步完成
① 确定“刘晨”所在系名

SELECT  Sdept  
FROM     Student                            
WHERE  Sname= '刘晨';

结果为: CS
② 查找所有在CS系学习的学生。

SELECT   Sno, Sname, Sdept     
FROM      Student                 
WHERE   Sdept= 'CS'; 

在这里插入图片描述
第二种方法:将第一步查询嵌入到第二步查询的条件中

SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept  IN
              (SELECT Sdept
               FROM Student
               WHERE Sname= '刘晨');

此方法为不相关子查询
在这里插入图片描述
第三种方法:用自身连接完成[例 3.55]查询要求

SELECT  S1.Sno, S1.Sname,S1.Sdept
FROM     Student S1,Student S2
WHERE  S1.Sdept = S2.Sdept  AND
                  S2.Sname = '刘晨';

在这里插入图片描述
[例 3.56]查询选修了课程名为“信息系统”的学生学号和姓名

SELECT Sno,Sname                 ③ 最后在Student关系中取出Sno和Sname
FROM    Student                          
WHERE Sno  IN
         (SELECT Sno                     ② 然后在SC关系中找出选 修了3号课程的学生学号
          FROM    SC                        
          WHERE  Cno IN
                 (SELECT Cno             ① 首先在Course关系中找出 “信息系统”的课程号,为3号
                   FROM Course           
                   WHERE Cname= '信息系统'                      
                )
          );

在这里插入图片描述

2.带有比较运算符的子查询

当能确切知道内层查询返回单值时,可用比较运算符(>,<,=,>=,<=,!=或< >)。
[例 3.57 ]找出每个学生超过他选修课程平均成绩的课程号。

SELECT Sno, Cno
FROM    SC  x
WHERE Grade >=(SELECT AVG(Grade)
                         FROM  SC y
                           WHERE y.Sno=x.Sno);

在这里插入图片描述

3.带有ANY(SOME)或ALL谓词的子查询

使用ANY或ALL谓词时必须同时使用比较运算
语义为:

ANY 大于子查询结果中的某个值
ALL 大于子查询结果中的所有值
< ANY 小于子查询结果中的某个值
< ALL 小于子查询结果中的所有值
= ANY 大于等于子查询结果中的某个值
= ALL 大于等于子查询结果中的所有值·

[例 3.58] 查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄

SELECT Sname,Sage
FROM    Student
WHERE Sage < ANY (SELECT  Sage
                                     FROM    Student
                                     WHERE Sdept= ' CS ')
 AND Sdept <> ‘CS ' ;           /*父查询块中的条件 */

在这里插入图片描述
执行过程:
(1)首先处理子查询,找出CS系中所有学生的年龄,构成一个集合(20,19)
(2)处理父查询,找所有不是CS系且年龄小于 20 或 19的学生
用聚集函数实现[例 3.58]

 SELECT Sname,Sage
FROM   Student
WHERE Sage < 
                     (SELECT MAX(Sage)
                       FROM Student
                       WHERE Sdept= 'CS')
AND Sdept <> 'CS';

在这里插入图片描述
[例 3.59] 查询非计算机科学系中比计算机科学系所有学生年龄都小的学生姓名及年龄。
方法一:用ALL谓词

SELECT Sname,Sage
FROM Student
WHERE Sage < ALL
                   (SELECT Sage
                    FROM Student
                    WHERE Sdept= 'CS')
AND Sdept <> 'CS';

在这里插入图片描述
方法二:用聚集函数

SELECT Sname,Sage
FROM Student
 WHERE Sage < 
                           (SELECT MIN(Sage)
                            FROM Student
                            WHERE Sdept= ' CS ')
      AND Sdept <>' CS ';

在这里插入图片描述

在这里插入图片描述

发布了15 篇原创文章 · 获赞 8 · 访问量 4027

猜你喜欢

转载自blog.csdn.net/tutouxiaogangpao/article/details/104918322