问题是: 检索至少选修“程军”老师所授全部课程的学生姓名SNAME。 答案是:SELECT SNAME
  FROM S
  WHERE NOT EXISTS
      (SELECT *
      FROM C
       WHERE TEACHER=’程军’ AND NOT EXISTS  
             (SELECT *
            FROM SC
            WHERE SC.SNO=S.SNO AND  SC.CNO=C.CNO));  S#=SNOC#=CNO
 还是有点不理解,麻烦看下我的思路:第一个select查询:假设SNO=1第二个select查询,取C表中的CNO=K5SC.SNO=1, SC.CNO=K5这时候无数据,所以第二个selct查询的not exists 成立然后我就不知道怎么执行了……我猜得:然后给出K5的结果,因为是存在的,为真,所以第一个not exists就不成立? 第一个select查询:假设SNO=2第二个select查询,取CNO=K5SC.SNO=1, SC.CNO=K5这时候有数据,所以第二个selct查询的not exists 不成立,既然这里不成立那么where里的not exists为假了,那这个select还 怎么执行?所以这整个句子为假 第一个not exists就为true了?有没有人能给通俗点的解释。马上要考试了....

解决方案 »

  1.   

    --1.至少一门:
    select a.sname from s a where exists(select 1 from sc inner join c on sc.cno=c.cno where sc.sno=a.sno and c.techer='程军')
    --2.必须全部:
    select a.sname from s a inner join sc b on a.sno=b.sno inner join c on b.cno=c.cno group by a.sname having count(*)<
    (select count(*) from c where techer='程军')
      

  2.   

    就是程军的课必须选 其他的课可有可无答案我这写了 但是就是不理解exists的用法
      

  3.   

    这个要从后面向前来理解:
    从s表中查找记录,不存在这样一种情况:
    C表中有一条teacher为程军的记录,其cno不能在sc表中找到(即sc表中的cno为c表中的cno,但前提是sno为当前查询的s表的sno相同).