嵌套查询
- 一个SELECT-FROM-WHERE语句称为一个查询块
- 将一个查询块嵌套在另一个查询块的WHERE字句或HAVING短语的条件中的查询叫做嵌套查询。
- Order by不能出现在嵌套块中。
- 上层查询块称外层或父查询,下层称内层或子查询。
- SQL允许多层嵌套。
按相关性(嵌套查询的求解过程)划分嵌套查询:
不相关子查询
子查询的查询条件不依赖于父查询。故有里向外逐层处理。
相关子查询
子查询的查询条件依赖于父查询。
- 取外层查询中表的第一个元素,根据与内层查询相关的属性值处理内层查询,若Where子句返回真,则此元组放入结果表中。
- 从外层表中取下一个元组,重复直至检查完毕。
按谓词划分嵌套查询:
1、带In谓词的子查询
In谓词即集合的所属关系。
查询与“刘晨”在同一个系学习的学生
SELECT Sno,sname,sdept
From Student
Where Sdept In
(Select Sdept
From Student
Where Student.Sname='刘晨')
//为不相关查询
查询选修了课程名为信息系统的学生学号和姓名。
两种方法:
一、嵌套查询
Select Sno,Sname
From Student
Where Sno in
(Select sno
From SC
Where cno In
(Select Cno
From Course
Where Cname='信息系统'))
二、连接查询
Select Student.Sno,Sname
From Student,SC,Course
Where Student.Sno=SC.Sno AND
SC.Cno=Course.Cno And
Course.Cname='信息系统'
2、带有比较运算符的子查询
当确切知道内层查询返回值为单值时,可用比较运算符
找出每个学生超过他选修课程平均成绩的课程号
Select Sno,Cno
From SC x
Where Grade>=(Select AVG(Grade)
From SC y
Where x.Sno=y.Sno)
3、带有ANY或ALL谓词的子查询
ANY:查询结果汇总任意一个值
ALL:查询结果汇总全部值
EXIST:查询结果是否为空,空返回false,不空返回true。
查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名和年龄。
Select Sname,sage
From Student
Where Sage<ANY(SELECT Sage
From Student
Where Sdept='CS')
AND Sdept<>'CS'
//<>为不等于
//如查询非计算机科学系中比计算机科学系所以一个学生年龄小的学生姓名和年龄,则将ANY改为ALL
4、带EXISTS谓词的子查询
由EXISTS引出的子查询,目标列通常为*,因为其只返回真值或假值,给出列名无意义。
查询没有选修1号课程的学生姓名。
Select Sname
From Student
Where Not EXISTS
(SELECT *
FROM SC
WHERE SC.Sno=Student.Sno AND Cno='1')
EXISTS/NOT EXISTS可实现全程量词(难点),例子如下:
查询选修了所有课程的学生姓名
Select Sname
From Student
Where NOT EXISTS /位置2/
(SELECT *
FROM Course
WHERE NOT EXISTS /位置1/
(SELECT *
FROM SC
WHERE Student.Sno=SC.Sno AND
SC.Cno=Course.Cno))
理解:若一个学生选修了所有课程,则位置1始终为false,则位置2为true,该学生信息进入结果表
若一个学生漏选了某个课程,则位置1有一次为true,则位置2和1之间的Select有一个值,则位置2为false,信息不能进入结果表。
否定的否定即肯定!
EXISTS/NOT EXISTS实现逻辑蕴涵(难点)
SQL中没有蕴含逻辑运算,已知蕴含谓词表达式:
查询至少选修了学生200215122选修的全部课程的学生。!!!!!!!!重要!我不会!
SELECT *
From Student S1
Where NOT EXISTS /位置2/
(SELECT *
FROM SC S2
WHERE S2.Sno='200215122' AND
NOT EXISTS /位置1/
(
SELECT *
FROM SC S3
WHERE S1.Sno=S3.Sno AND
S2.Cno=s3.Cno
))
理解同上:若一个学生选修了200215122的所有课程,则位置1始终为false,则位置2为true,该学生信息进入结果表
若一个学生漏选了200215122的某个课程,则位置1有一次为true,则位置2和1之间的Select有一个值,则位置2为false,信息不能进入结果表。