--你的查询语句应该是这样的吧?
select Sname from student
where not exists(
  select *  from course
    where not exists(
       select * from sc where Sno=student.Sno and Cno=course.Cno
                    )
                 )

解决方案 »

  1.   

    --它的执行原理基本上可以这样理解(实际的执行机制就不管了):逐条扫描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   --这时,两个条件要判断的值都已经知道查询就可以得到结果,看是否存在记录.然后将结果返回外层查询.
      

  2.   

    exists:先执行主查询后子查询
    in:先执行子查询后主查询具体使用哪一个视主查询和子查询大小而定。
      

  3.   

    刚才zjcxc(邹建)是从外到里分析,下面从里到外来说select Sname   //将选了所有课程的学生姓名选出
    from student
    where not exists
      select *            //课程表中没有改学生未选的课程,即该学生选了所有课程
      from course
      where not exists
        (select *
         from sc
         where Sno=student.Sno and Cno=course.Cno)  //查询出改学生所选了哪些课程
      

  4.   

    这样分析好象不是很准确。有执行顺序的,先执行exists所带的子查询的。
      

  5.   

    create table #STUDENT(SID int,Sname varchar(10))
    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))
      

  6.   

    zjcxc(邹建)关于执行原理的分析已经很清楚了。
    现在,我来解释实际的意义。
    对于学生表中的每一条记录(即为一个学生),与课程表中的每一条(即为一门课程)组合,看组合出来的成果(我们称为组合A,组合A是学生可以选的所有课程)是不是在成绩表(成绩表也是学生的选课表)中。如果选课表中不存在组合A,就返回这名学生未选的课程,如果这名学生没有未选的课程,则,意味着该学生选了所有的课程。
    当学生表扫描结束,则得出“选了所有课程的学生”
      

  7.   


    这样理解:双重否定等于肯定!
    有最里开始
    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,理解起来也会更容易点!
      

  8.   

    to zjcxc(邹建):若扫描到student表中“99001”记录与course中“1”记录时,作select * from sc where Sno=99001 and Cno=1    查询得到一个存在的选课记录。  那么是否要将这个记录返回?若要返回的话,返回到哪层查询?
      

  9.   

    不是将记录返回,是返回查到记录的标志.
    逐条扫描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条件为假,没有记录则为真.
    然后再返回上层.
      

  10.   

    exists:即判斷了查詢是否有記錄﹐是一個邏輯值﹐true/false常與if結合使用
      

  11.   

    to zjcxc(邹建):"这时,如果有记录,则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()进行查询。这下一步是怎样进行的呢????????
      

  12.   

    Exists的效率高就高在“只返回是否存在满足条件的记录,而是不查出满足条件的记录”
      

  13.   

    zjcxc(邹建)关于执行原理的分析已经很清楚了