我正在阅读Hank Korth的数据库系统概念。书中说明以下列出了所有已经学过的所有课程的学生 在生物系。
select distinct S.ID, S.name
from student as S
where not exists (
(
select course id
from course
where dept name = 'Biology'
)
except
(
select T.course id
from takes as T
where S.ID = T.ID
)
);
student(ID, name, dept name, tot cred)
course(course id, title, dept name, credits)
takes(ID, course id, sec id, semester, year, grade)
但是,根据我的理解,最后一个子查询找到所有至少参加过一门课程的学生,并且通过从第一个子查询中减去,我们将减去学生目前正在学习的所有生物课程,因此我们将离开生物学课程不是任何学生(如果有的话)。然后,当我们对所有学生证书“不存在”时,我们正在寻找没有参加那些生物学课程的学生证,而且他们可以选择除了生物学。但是没有列出正在参加生物学系提供的所有课程的学生名单。有人可以解释一下吗? 请注意:我确实理解this中“不存在”的用法 网站,但我没有得到这本书的例子。
答案 0 :(得分:1)
我认为您缺少的是NOT EXISTS子查询独立执行,对于外部查询返回的每个行。
请注意,它是相关的子查询。这是对外部查询S.ID
中的列的引用。
每次执行子查询时都会传入一个S.ID
值。因此,如果学生正在学习生物系的所有课程,则子查询中的EXCEPT
操作将导致空集。并且NOT EXISTS将评估为TRUE。但是如果子查询返回一行,那么至少在生物学课程中,学生不会参加。