一:exists和in的比较
(1)exists是用于判断是否存在,当exists(查询语句)中的“查询语句”如果有查询结果则返回true,否则返回false
select * from xxx where exists(....) exists作为where条件时,语句的执行流程是这样的:
先执行where条件前的主查询,然后用主查询的结果一行一行元素组的代入exists的子查询进行判断,如果exists返回真则输出主查询的
这条结果,否则不输出。(相当于先将外查询结果查出来然后对每行结果进行一个遍历,看是否满足条件,满足则输出,不满足作为舍去)
(2)in,在in的查询语句中却是正好相反,先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。在执行子查询之前,系统会
先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。
结论:个人认为:exists更适合外表小内表大的情况,in更适合外表大,内表小的情况(先执行的尽量小)
二:实例
参照某PPT
(1)查找学好为95003的学生没有选修的课程
方法一:in
select * from course where Cno not in (select Cno from sc where Sno=95003)
方法二:exists
思路:①把已知学好95003代入,②把每一个科目代入(循环)③:将前两个条件组合,一一与SC表中的学号(95003)和科目进行对比,找不到匹配的就是95003没有选修的科目。
select * from course
where not exists //找不到的进行提交给course
(select * from SC where course.cno=cno and sno=95003) //在SC进行匹配
(2)查找一门选修科目都没选的学生
方法一:in
select * from student where Sno not in (select Sno from sc )
方法二:exists
select * from student where not exists
(select * from sc where student.Sno=Sno )//将学生表内的学号循环代入到学生成绩表,一旦遇到查询无结果的则输出主查询的结果,即是需要的!
(3)查找选修了所有选修课的学生
方法一:in
select * from student where Sno in (select Sno from sc group by Sno having count(*)=(select count(*) from course ))
方法二:exists
因为in 和exists 是存在和不存在的情况使用,遇到是否所有都存在,这种情况直接用这两个是无法达到的,可以使用其相反的思路:所有存在就是没有一个不存在。同理这里需要选出选修了所有选修课的学生,按如下看对于学号和课程使用exists只能是查到在或不在的情况。所有这里改成“选修所有课程的学生”==“没有课程没有选的学生”
select * from student where not exists
(
select * from course where not exists
(
select * from sc where Cno=course.Cno and Sno=student.Sno
)
)
(4)查找选修了95002选修的所有课程的人
对于这种需要同时满足多个值的SQL使用in或not in 就无法实现了。因为in ,not in 表示在或不在