混淆空关系测试使用'not exitst'

时间:2017-02-12 03:16:55

标签: sql oracle

我正在阅读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中“不存在”的用法 网站,但我没有得到这本书的例子。

1 个答案:

答案 0 :(得分:1)

我认为您缺少的是NOT EXISTS子查询独立执行,对于外部查询返回的每个行。

请注意,它是相关的子查询。这是对外部查询S.ID中的列的引用。

每次执行子查询时都会传入一个S.ID值。因此,如果学生正在学习生物系的所有课程,则子查询中的EXCEPT操作将导致空集。并且NOT EXISTS将评估为TRUE。但是如果子查询返回一行,那么至少在生物学课程中,学生不会参加。