学生选课信息共三个表:
S:学生基本信息
sno sname
95001 | 李二 |
---|---|
95002 | 王三 |
95003 | 赵四 |
95004 | 孙小毛 |
95005 | 王大侃 |
C:课程基本信息
cno cname
1 | 逻辑与幽默 |
---|---|
2 | 电影艺术欣赏 |
3 | 大学生文化之道 |
4 | 领导魅力论 |
SC:选课信息
sno cno
95001 | 1 |
---|---|
95002 | 3 |
95004 | 4 |
95005 | 2 |
95001 | 3 |
95001 | 2 |
95001 | 4 |
首先得搞懂嵌套查询中相关子查询的执行过程:
首先选取父查询表中的一个元组,内部的子查询利用此元组中的相关属性值进行查询
然后父查询根据子查询返回的结果判断此行是否满足查询条件,若满足,则把该行放入父查询的查询结果中。
相当于一个循环,逐个的实验。
我们先来看看这个问题
问题一、
查询学号为‘95002’的学生选修的课程信息
select * from C where exists (select * from SC where SC.cno = C.cno and SC.sno = '95002' );
按照上述的相关子查询的执行过程:
C表中共有课程号为1,2,3,4的四门课,子查询把这四个学号对应的四个元组逐一带入,
根据子查询中的条件SC.cno = C.cno and SC.sno = '95002'
当C.cno = 1, 不存在符合条件的元组,exists返回false,父查询中不把该C.cno对应的元组放到查询结果中
当C.cno = 2,存在符合条件的元组,exists返回true,父查询中把该C.cno对应的元组放到查询结果中
当C.cno = 3 .......
当C.cno = 4 .........
逐一查询之后,就把C.cno =2 对应的元组选出来了
同理问题二、
查询学号为‘95002’未选修的课程就是
select * from C where not exists (select * from SC where SC.sno = ‘95002’ and SC.cno = C.cno);
好了,接下来我们分析文章开始提出的问题:
select * from S where not exists
(select * from C where not exists
(select * from SC where SC.sno = ‘95002’ and SC.cno = C.cno));
还记得我们学过的
for(i= 0 ;i < 5;i++)
for(j = 0; j < 4;j++)
某语句;
仿照上述的分析过程S表中学号分别为95001,.....,95005对应的五个元组
当Sno =95001时,这个问题就又转化为问题二了。学号为95001的学生未选修的课程是否为空,为空的的话保留。
........
遍历完学生信息表中的元组之后,也就把所有符合条件的元组选出来了。