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

关系模式:学生(学号,姓名,系别,年龄)课程(课程号,课程名,学时)选读(学号,课程号,成绩)问题:检索选读全部课程的学生姓名select学生.姓名from学生where... 关系模式:
学生(学号,姓名,系别,年龄)
课程(课程号,课程名,学时)
选读(学号,课程号,成绩)
问题:检索选读全部课程的学生姓名
select 学生.姓名 from 学生
where not exists(
select * from 课程 where not exists(
select * from 选读 where 学号=学生.学号 and 课程号=课程.课程号))

小弟对整个查询的大致步骤,以及为什么用not exists不理解,望高手赐教.
感谢几位的解答,尤其是nomanland兄.我还有个问题:最里面的子查询的from句为什么不是"from 学生,课程,选读"? 要不然where句怎么可以调用三个关系的属性呢?
展开
 我来答
WHITE_WIN
2008-03-10 · TA获得超过6111个赞
知道大有可为答主
回答量:3759
采纳率:50%
帮助的人:1915万
展开全部
现在我们从后面的子查询向前分解:

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中规定:所有子表都是可以通过表名调用其上面任意层次的表中的字段的。所以,不是只有内联接才可以调用多个表的属性。
woshidaniel
2015-08-04 · TA获得超过9240个赞
知道小有建树答主
回答量:1760
采纳率:96%
帮助的人:954万
展开全部

not exists (sql 不返回结果集为真)

如下: 
表A 
ID NAME 
1    A1 
2    A2 
3  A3 

表B 
ID AID NAME 
1    1 B1 
2    2 B2 
3    2 B3 
SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID) 
执行结果为 
3 A3
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
朱满福
2008-03-07 · 超过48用户采纳过TA的回答
知道小有建树答主
回答量:146
采纳率:50%
帮助的人:38.5万
展开全部
select * from 课程 这个结果集
在select * from 选读 where 学号=学生.学号 and 课程号=课程.课程号)) 结果集中不存在;
具体的打开查询分析器 按 F1 在关键字处 键入exists
回车 就可以看到他的具体用法
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
hzp309
2008-03-07
知道答主
回答量:11
采纳率:0%
帮助的人:0
展开全部
代码应该如下:
select 学生.姓名 from 学生
where not exists(
select * from 课程 where not exists(
select * from 选读 where 学号=学生.学号 and 课程号=课程.
exists是查找一张表的数字集,而not exists是数字集的反集.如果子查询不返回行,那么使用 NOT EXISTS 的 WHERE 子句会得到令人满意的结果。
要查找不出版商业书籍的出版商的名称:

USE pubs
SELECT pub_name
FROM publishers
WHERE NOT EXISTS
(SELECT *
FROM titles
WHERE pub_id = publishers.pub_id
AND type = 'business')

下面是结果集:

pub_name
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
furier
2008-03-11 · TA获得超过260个赞
知道小有建树答主
回答量:235
采纳率:0%
帮助的人:226万
展开全部
简单说,就是查询没有选课的学生的姓名。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式