一般数据库关联查询,首先想到的是多表连接查询,而不用子查询,原因是多表连接查询比子查询效率高(因为查询优化器可以对多表连接查询进行更多的优化。
但是当查询出现否定条件的时候,为了避免查询时的数据不准确,一般使用子查询,例
表一 student 学生信息
字段包括:sno sname sage
表二 sc 学生选课信息
字段包括:sno(外键) cno(课程) grade(成绩)
当要查询没有选修‘C01’课程的学生姓名时
1.一般想到用多表关联
select distinct s.sname from student s join sc on s.sno=sc.sno where cno!='C01'
但是结果是错的,因为对于多表关联查询,所有的条件都是在连接之后的结果表上进行的,而且是逐一进行判断的,当发现cno!='C01'的否定条件,就会将这条记录查询出来,那么这个结果必然包括,没有选修C01号课程的学生,但同时也包括了选修C01同时又选修了其他课程的学生。
2.使用子查询
select Sname from student where sno in (select sno from sc where cno !='C01');
会出现和1一样的问题
3.将否定放在外层
select Sname from student where sno not in (select sno from sc where cno ='C01');
这样的查询结果就是正确的