赞
踩
选课表:学号StudentNo、课程号CourseNo
学生表:学号StudentNo、姓名StudentName
课程表:课程号CourseNo、课程名CourseName
In语句查询:
- select StudentName from 学生表
- where StudentNo in (select StudentNo from 选课表 where CourseNo=‘C1’)
Exists查询:
- select StudentName from 学生表
- where exists (select 1 from 选课表 where 选课表.StudentNo=学生表.StudentNo and 选课表.CourseNo='C1')
相关子查询执行过程:先在外层查询中取“学生表”的第一行记录,利用该记录的相关属性值(在exists子查询的where子句中用到的列)处理内层查询,若外层的where子句返回“true”,则本条记录放入结果表中。然后再取下一行记录,重复上述过程直到外层表遍历完毕。
Exists语句不关心子查询返回的具体内容,因此用“exists(select 1 from)”来判断子查询是否返回记录。
- select StudentName from 学生表
- where not exists (select 1 from 选课表 where 学生表.StudentNo=选课表.StudentNo and CourseNo=‘C1’)
- --外层查询、外层not exists
- select StudentName from 学生表 where not exists
- (
- --内层查询、内层not exists
- select 1 from 课程表 where not exists
- (
- select 1 from 选课表 where 学生表.StudentNo=选课表.StudentNo and 课程表.CourseNo=选课表.CourseNo
- )
- )
a、选一行学生信息S1、选一行课程信息C1
内层的not exists()值为true,说明选课表中找不到“S1.StudentNo + C1.CourseNo”这一记录,说明学生S1没有选课程C1,此时内层查询的返回结果集会加上C1,当内层查询的返回结果集不为空时,外层not exists()值为false,则外层where子句值为false,则S1被排除。
当内层查询的返回结果集不为空时,说明S1至少有一门课程没选 。
b、选一行学生信息S1、选一行课程信息C2
内层的not exists()值为false,说明选课表中有“S1.StudentNo + C2.CourseNo”这一记录,说明学生S1选了课程C2,此时内层查询的返回结果集不会加上C2,当内层查询的返回结果集为空时,外层not exists()值为true,则外层where子句值为true,则S1被选中。
当内层查询的返回结果集为空时,说明S1已经选了所有课程。
c、结果
外层查询最终返回的结果是选择了所有课程的学生。
- --外层查询、外层not exists
- select StudentName from 学生表 where not exists
- (
- --内层查询、内层not exists
- select 1 from 课程表 where CourseNo in('C1','C2') and not exists
- (
- select 1 from 选课表 where 学生表.StudentNo=选课表.StudentNo and 课程表.CourseNo=选课表.CourseNo
- )
- )
第五条查询的是选修了所有课程的学生,如果我们将所有课程限定为“C1、C2”,那查询结果就变为选修了C1、C2的学生,该结果保证学生至少选修了C1、C2,但是选没选其他课不清楚。
- --外层查询、外层not exists
- select StudentName from 学生表 where not exists
- (
- --内层查询、内层not exists
- select 1 from 选课表X where 选课表X.StudentNo='S1' and not exists
- (
- select 1 from 选课表Y where 学生表.StudentNo=选课表Y.StudentNo and 选课表X.CourseNo=选课表Y.CourseNo
- )
- )
第五条查询的是选修了所有课程的学生,如果我们将所有课程限定为S1所选的全部课程,那查询结果就变为选修了S1所选的全部课程的学生,该结果保证学生至少选修了S1所选的全部课程,但是选没选其他课不清楚。
- --定义表名可以用as也可以不用as
- select StudentName,avgScore,CreateDate from
- (select StudentName,CreateDate,AVG(Score) from StudentScores group by StudentName,CreateDate)as ta(StudentName,avgScore,CreateDate)
- where CreateDate>80
-
- --定义表名可以用as也可以不用as
- select StudentName,avgScore,CreateDate from
- (select StudentName,CreateDate,AVG(Score) from StudentScores group by StudentName,CreateDate)ta(StudentName,avgScore,CreateDate)
- where CreateDate>80
最后,我要感谢SQL中EXISTS的使用 - 咖啡无眠 - 博客园的无私奉献!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。