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

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

1.  SELECT
2. 		Sname 
3.    FROM S 
5. 		WHERE NOT EXISTS ( 
6.					SELECT * FROM course WHERE NOT EXISTS ( 
7.					SELECT * FROM SC WHERE Sno = student.Sno AND Cno = course.Cno ) );

WHERE后面的 NOT EXISTS()表示条件判断,当括号内没有符合条件的元组时,返回TRUE,否则返回FALSE.

然后我们根据题意进行逻辑转换:
学生 选择 全部课程 = 学生 不存在 没有选的课

  SELECT Sname  FROM S WHERE NOT EXISTS (没有选的课 )

没有选的课=课 不存在 已经被选

SELECT * FROM course WHERE NOT EXISTS ( 已经被选 )

已经被选的课

SELECT * FROM SC WHERE Sno = student.Sno AND Cno = course.Cno

这就是大体的思路,但是我们要想一下为什么要这样做?

首先我想先说明一下EXISTS()和 NOT EXISTS() 。我们知道 WHERE 后面的式子表示条件判断,当返回的值为 TRUE 时,才进行前面的选择,当返回的值为 FALSE 时,则不进行选择。

EXIEST()表示当括号里存在元组时,返回TRUE。(有一项存在即可
NOT EXISTS()表示当括号里不存子元组时,返回TRUE。(必须是全部,没有一项存在

我们现在开始从头往后捋,我们要选择学生姓名,期待后面的条件是TRUE,而我们的条件是选修全部课程,所以用 NOT EXISTS()比较合适。然后我们再次选择没有被选的课,期待后面的条件是TRUE,我们很容易想到用EXISTS()来找到其中一个学生与课程不对应的就行,但是我们SC表中存储的是学生对应的选课关系,没有被选的课需要用到否定来转换,既可以用NOT EXISTS()来表示。

我们可能又有疑问了,不是要根据全部或其中之一这个条件来选择吗?
我们应当注意,在第一个选择时是一对多,而在第二次选择时,已经代入了上一层的学生,进行的是一对一的选择,此时NOT EXISTS()和EXISTS()表示一样。

  • 17
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值