最近在复习MySQL查询操作,课本上有两个例子感觉理解起来略显晦涩,特记录下来:
- 查询选修了全部课程的学生姓名
- 查询至少选秀了学生201215122选修的全部课程的学生号码
对于第一个问题,它可以等价于不存在一门课程是该学生没有选的。
那么首先,我们可以分析到开始一定是查询学生的姓名:
select sname
from student
where + 条件
那么条件是什么呢?“不存在一门课他没有选”
not exists + 有课程他没有选修,也就是要把course中的所有课程拿出来找,找到他没有选修过的。
select * from course
where + 条件
这个条件又是什么呢?
只要在最后一个select 中
select * from SC
where Sno= Student.Sno
and Cno= Course.Cno
将这个同学通过 SC 表 和 Crouse的 课程连接一遍,找到连接不上的,即: 没有选修的, 这样就找到了一门课这个学生没有选修, 存在没有选修的课,那么该学生被pass掉了。
最后我们可以构造以下SQL语句:
select sname
from student
where not exists
(select *
from course
where not exists
(select *
from SC
where Sno = student.Sno
AND cno = course.Cno))
第二个问题,变换后,它等价于:不存在这样的课程y,学生201215122选修了y,而学生x没有选
select DISTINCT Sno
from SC s1
where not exists // 不存在
(
select *
from SC s2
where s2.Sno='201215122' and not exists // 201215122选了,y学生没有选(对于被20121522选了的Cno)
(
select * //这门课在x中没被选择
from SC s3
where s1.Sno=s3.Sno and s3.Cno=s2.Cno //在x的选课列表中搜索这门课
)
);
参考文档:
https://www.cnblogs.com/losesea/archive/2012/10/10/2718093.html
http://www.voidcn.com/article/p-kimitpum-gb.html