not exists在嵌套子查询中如何理解?

来源:百度知道 编辑:UC知道 时间:2024/05/18 01:40:31
关系模式:
学生(学号,姓名,系别,年龄)
课程(课程号,课程名,学时)
选读(学号,课程号,成绩)
问题:检索选读全部课程的学生姓名
select 学生.姓名 from 学生
where not exists(
select * from 课程 where not exists(
select * from 选读 where 学号=学生.学号 and 课程号=课程.课程号))

小弟对整个查询的大致步骤,以及为什么用not exists不理解,望高手赐教.
感谢几位的解答,尤其是nomanland兄.我还有个问题:最里面的子查询的from句为什么不是"from 学生,课程,选读"? 要不然where句怎么可以调用三个关系的属性呢?

现在我们从后面的子查询向前分解:

1.所有未选过的课程的数据集:
select * from 课程 where not exists(
select * from 选读 where 课程号=课程.课程号)

2.所有没被某位学号为 @学号 的学生选过的课程的记录集(@学号学生的未选课程):
select * from 课程 where not exists(
select * from 选读 where 学号=@学号 and 课程号=课程.课程号)
请注意,多出了学号的筛选即,学号=@学号。

3.遍历每一个主查询的学号,每一个学号都按第二筛选方法筛选出:没有未选课程的学生的学号。(不包括在第查询方法查询出的“有未学课程的学号的记录集”中的记录。)
请注意:用主查询中的 学生.学号 代替了@学号。
select 学生.姓名 from 学生
where not exists(
select * from 课程 where not exists(
select * from 选读 where 学号=学生.学号 and 课程号=课程.课程号))

这已经是整个查询语句,可以看出子查询中用学生.学号替换了第2步中的 @学号,(没忘了吧,第二步求的是没有选修全部课程的某个学生)。

用上面的讲解方法不知道是不是更好理解一点。

===============

针对您最后的补充:

为什么不用
from 学生,课程,选读?

答:因为from 学生,课程,选读 也就是
SELECT * FROM 学生,课程,选读 WHERE .....条件
这样的型式只能组成内联接,而内联接我们只知道,只有三个表按联接条件都符合才会被选中,而我们要的是有不符合后面两表的的学生才符合条件,所以用内联接是不可行的。

要不然where句怎么可以调用三个关系的属性呢?

答:在SQL SERVER中规定:所有子表都是可以通过表名调用其