赞
踩
- 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,即该学生不符合条件,因此该学生将不会被返回。其他学生同样不满足条件,因为他们也没有选齐所有的课程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。