--你的查询语句应该是这样的吧?
select Sname from student
where not exists(
select * from course
where not exists(
select * from sc where Sno=student.Sno and Cno=course.Cno
)
)
select Sname from student
where not exists(
select * from course
where not exists(
select * from sc where Sno=student.Sno and Cno=course.Cno
)
)
扫描每一条的时候,假设sno=x,开始去判断条件,即执行:
select * from course
where not exists(
select * from sc where Sno=x --因为这时已经知道student.Sno=x
and Cno=course.Cno
)
这时,又是一个子查询,它又逐条扫描course的每条记录.
扫描每一条的时候,假设cno=xx,这时,外部查询还有一个条件sno=x,就是有两个条件.然后开始去判断条件,即执行:
select * from sc where Sno=x and Cno=xx --这时,两个条件要判断的值都已经知道查询就可以得到结果,看是否存在记录.然后将结果返回外层查询.
in:先执行子查询后主查询具体使用哪一个视主查询和子查询大小而定。
from student
where not exists
select * //课程表中没有改学生未选的课程,即该学生选了所有课程
from course
where not exists
(select *
from sc
where Sno=student.Sno and Cno=course.Cno) //查询出改学生所选了哪些课程
insert #student values(1,'WAN')
insert #student values(2,'NAM')
insert #student values(3,'DNA')create table #COURCE (CID int,CNAME varchar(2))
insert #COURCE values(1,'EN')
insert #COURCE values(2,'CN')
insert #COURCE values(3,'US')create table #SC(SID int,CID int,SCORE int)
insert #sc values(1, 1 , 90)
insert #sc values(1 , 2 , 67)
insert #sc values(1 , 3 , 30)
insert #sc values(2 , 3 , 46)
insert #sc values(3 , 1 , 89)--求有参加过课程的人
select sname from #student where exists(
select * from #cource where exists(
select * from #sc where #sc.sid=#student.Sid and
#sc.cid=#cource.cid))--求有没有参加课程的人
select sname from #student where exists(
select * from #cource where not exists(
select * from #sc where #sc.sid=#student.Sid and
#sc.cid=#cource.cid))--求有参加所有课程的人
select sname from #student where not exists(
select * from #cource where not exists(
select * from #sc where #sc.sid=#student.Sid and
#sc.cid=#cource.cid))
现在,我来解释实际的意义。
对于学生表中的每一条记录(即为一个学生),与课程表中的每一条(即为一门课程)组合,看组合出来的成果(我们称为组合A,组合A是学生可以选的所有课程)是不是在成绩表(成绩表也是学生的选课表)中。如果选课表中不存在组合A,就返回这名学生未选的课程,如果这名学生没有未选的课程,则,意味着该学生选了所有的课程。
当学生表扫描结束,则得出“选了所有课程的学生”
这样理解:双重否定等于肯定!
有最里开始
select *
from sc
where Sno=student.Sno and Cno=course.Cno检索当前学生的成绩单,进一步可以理解为选修了那些科目紧接着那么下面的
select *
from course
where not exists
(select *
from sc
where Sno=student.Sno and Cno=course.Cno)理解为当前学生没有许修的科目,如果理解不了你可以比较着理解
select *
from course
where exists
(select *
from sc
where Sno=student.Sno and Cno=course.Cno)
去掉not 这段sql返回当前学生选修那些课程。加了not呢!
即是上面讲到的当前学生'没有'选修的科目!
最后
select Sname
from student
where not exists(
select *
from course
where not exists
(select *
from sc
where Sno=student.Sno and Cno=course.Cno))
可以理解为
不存在-> 当前学生学生没有许修的科目->即是选修了全部的科目-----------------------------
不知道说清出了没有,随着不断的学习T_SQL,理解起来也会更容易点!
逐条扫描student中的每条记录.
扫描每一条的时候,假设sno=x,开始去判断条件,即执行:
select * from course
where not exists(
select * from sc where Sno=x --因为这时已经知道student.Sno=x
and Cno=course.Cno
)
这时,又是一个子查询,它又逐条扫描course的每条记录.
扫描每一条的时候,假设cno=xx,这时,外部查询还有一个条件sno=x,就是有两个条件.然后开始去判断条件,即执行:
select * from sc where Sno=x and Cno=xx --这时,两个条件要判断的值都已经知道
查询就可以得到结果,看是否存在记录.然后将结果返回外层查询.即判断
select * from course
where not exists(是否有记录) 这时,如果有记录,则where条件为假,没有记录则为真.
然后再返回上层.
然后再返回上层."这句能否再解释清楚些?
我的思路如下:
如果作select * from sc where Sno=99001 and Cno=1 查询得到一个存在的选课记录。 将它返回并作查询 select * from course where not exists(是否有记录) 则course表中的Cno=1记录不返回到select Sname from student where not exists()进行查询 ,而是扫描指针继续往下移即移到Cno=2号记录再作select * from sc where Sno=99001 and Cno=2 若这时没有该记录即该生没有选2号课程,则返回Cno=2记录到select Sname from student where not exists()进行查询。这下一步是怎样进行的呢????????