日期:2014-05-16  浏览次数:20535 次

一道SQL题目,求解释
表结构:
学生表:Student (sNO, sName, mNO, sSex, sBirth, sNative, sHeight, sWeight, sEntime)  其中sNO是学号,mNO是专业号
选课表:Student_Course(sNO, ccNO, NormalMark, ExamMark, Mark) 其中 ccNO是课程编号
课程表:Course_Class(ccNO, cNO, Term, tNO, CourseType, ExamType, Credit, Room, WeekTime, validity)  其中tNO是教师号
查询选修了全部已开课程的学生名。
答案提供了一种解法:
select  sNO, sName
from student s
where not exists (
    select * from course_class cc
    where not exists (
        select * from student_course sc
        where s.sNO=sc.sNO and sc.ccNO=cc.ccNO
    )
)
想了很久想不出上述解的原理,求解释。
还有,有没有别的解法?
------解决方案--------------------
引用:
这个写法叫结果集的除法,是种比较标准的写法,也比较难以理解,其实我觉得先从反方向理解比较好理解:
1.如果学生选择了所有的课程,那么就不存在既属于这个班级,又没被该学生选择的课程。
2.那么反过来说,如果学生没选择所有课程,那么就存在既属于这个班级,又没被学生选择的课程。
那么2.的语句怎么写呢?
SELECT *
FROM STUDENT ST
WHERE EXISTS(
--存在这样一个课程
SELECT 1 
FROM COURSE_CLASS CC
WHERE NOT EXISTS(
--这个课程既属于这个班级,又不属于这个学生
SELECT 1 
FROM STUDENT_COURSE SC
WHERE 
SC.SNO=ST.SNO
AND SC.CNO=CC.CNO
)

)

2.的逻辑比较好看懂,把2.的最外层的EXISTS改成NOT EXISTS,就是1.的逻辑了。

你可以把2的语句里的EXISTS再去掉,像这样:
SELECT *
FROM STUDENT ST
WHERE EXISTS(
--存在这样一个课程
SELECT 1 
FROM COURSE_CLASS CC
WHERE EXISTS(
--这个课程既属于这个班级,又属于这个学生
SELECT 1 
FROM STUDENT_COURSE SC
WHERE 
SC.SNO=ST.SNO
AND SC.CNO=CC.CNO
)

这个逻辑是什么呢:查询选修了至少一门课程的学生。