嵌套查询

1.带有EXISTS谓词的子查询(重点难点)

EXISTS代表存在量词,带有的EXISTS谓词的子查询不返回任何的数据,只产生逻辑值”true”或逻辑值”false”

[1] 查询所有选修了1号课程的学生姓名

1
2
3
4
5
6
SELECT sname
FROM student
WHERE EXISTS
(SELECT *
FROM sc
WHERE sc.sno = student.sno and sc.cno = 1)

解读:
先在student依次取每个元组的sno与sc表中的sno比较是否相等,
在相等的同时,再检查这个元组的cno属性是否为1

[2]查询选修了全部课程的学生姓名

sql中没有表示全称量词的关键字,因此我们需要将全部课程中的全部转换成存在量词的形式

记:”选修课程 x “ 这一事件 为 P

转换后的问题转化为: 不存在1门课,没有被他选修

将此问题分为两部分:

1.有门课没有被他选修。

2.不存在满足1条件的课

1
2
3
4
5
6
7
8
9
10
11
12
select sname -- 第一层
from student A
where not exsits
(select * -- 第二层
from course B
where not exists
(select * -- 第三层
from sc
where sc.sno = A.sno
and B.cno = C.cno
)
)

summary:如果每次都这样想,会较为复杂,如何处理?
首先明确,使用exists的情况为带有存在,全部等字样。现将其化为 谓词逻辑表达式,然后代入exists

[3]查询至少选修了学生201215122选修课程的全部课程的学生学号

将此问题转化成谓词逻辑表达式:

x 为学生

y 为课程

p代表谓词 “学生201215122选修了课程y”

用q代表谓词 “学生x选修了y”

同时sql中也没有蕴含的逻辑运算,因此还需要转换

1
2
3
4
5
6
7
8
9
10
11
12
13
select sno
from student
where not exists
(select *
from course
where sno = 201215122 and not exists
(
select *
from sc
where sc.sno = studente.sno -- 此处也可以换成 sno = student.sno
and sc.cno = course.cno -- 此处也可以换成 cno = course.cno
)
)