SELECT Sname
FROM Student
WHERE NOT EXISTS
(SELECT * FROM Course WHERE NOT EXISTS
(SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)
);
这是一个嵌套查询语句,可以解释为:
查询“Student”表中的“Sname”字段,但是只返回那些在“Course”表中拥有所有记录的学生。
具体地说,对于每个学生,如果该学生所选的所有课程都在“SC”表中有记录(即该学生选过这门课),则该学生符合条件。因此,如果一个学生有一个课程不在“SC”表中,则该学生将不会返回。
"Not Exists"的作用是在条件中使用子查询进行比较,并将结果与外部查询的结果进行比较。在这个例子中,如果内部子查询的结果集为空,则外部查询的条件成立。因此,使用"Not Exists"的目的是检查学生是否选择了所有课程。如果这个子查询中还存在没有选择的课程,则这个学生将不会被返回。
换句话说,这个查询将返回所有在“SC”表中出现的每个学生的名称,而没有在“SC”表中出现的学生将不会返回。
最重要的是如何理解Sno=Student.Sno AND Cno=Course.Cno ,当把一个学生Tom带入时,会判断这个学生在选课表SC中所选的所有课程是否都在Course中。
内部的子查询是SELECT * FROM Course WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)。这个子查询的意思是找出当前学生没有选择的课程。如果这个Tom有一门课没选,在这里会将Course的所有课程与SC中Tom选课比较,如果少一门课程那么在这里就会返回True ,那么在外层Not Exists 就会是False。如果没有一门课没选(就是都选了),那么这里会返回False,外层就是True,就会显示学生姓名。
我觉得这里最难理解的就是SELECT * FROM Course WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno)。这个子查询的意思是找出当前学生没有选择的课程。
假设有以下三张表:
Student表:
|
Sno |
Sname |
|
101 |
Tom |
|
102 |
Jerry |
|
103 |
Alice |
|
104 |
Bob |
Course表:
|
Cno |
Cname |
|
1 |
Math |
|
2 |
English |
|
3 |
History |
|
4 |
Geography |
|
5 |
ComputerSci |
SC表:
|
Sno |
Cno |
|
101 |
1 |
|
101 |
2 |
|
101 |
3 |
|
101 |
4 |
|
102 |
2 |
|
102 |
3 |
|
102 |
5 |
|
103 |
1 |
|
103 |
2 |
|
103 |
3 |
|
104 |
1 |
|
104 |
2 |
|
104 |
3 |
|
104 |
4 |
|
104 |
5 |
例子1:假设学生Tom已经选了所有的课程,而其他学生没有。我们带入上述SELECT语句:
sqlCopy codeSELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERENOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno) );
执行上述查询后,将返回Tom的名字,因为Tom是唯一选择了所有课程的学生。
例子2:假设学生Jerry少选了一门课(Geography),其他学生都没有选齐所有的课程。我们带入上述SELECT语句:
sqlCopy codeSELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERENOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno) );
执行上述查询后,将不会返回任何结果,因为Jerry没有选齐所有的课程。
这是因为在内部的NOT EXISTS子查询中,当存在一门课程(Geography)没有被选中时,将返回false,即该学生不符合条件,因此该学生将不会被返回。其他学生同样不满足条件,因为他们也没有选齐所有的课程。
该SQL查询用于从Student表中选取那些在Course表中选修了所有课程的学生。NotExists子查询检查每个学生在SC表中是否有完整记录。如果学生缺少任一门课程,则不会被返回。举例说明,Tom选修了所有课程,所以他的名字会被返回,而Jerry因未选修Geography,所以不会出现在结果中。
2008

被折叠的 条评论
为什么被折叠?



