IN --遍历 Exists --检索到满足条件即退出NOT EXISTS --检索到不满足条件即退出
例如:select * from tab1 where tab1.col1 in(select col2 from tab2) 改成exist语句可以这样的 select * from tab1 where exists(select 1 from tab2 where tab1.col1=tab2.col2) 如果表tab2中的col2有索引的话就能提高效率.而第一条语句中用不到tab2中的索引
表: 学生(学号,姓名,年龄,所在系) 课程(课程号,课程名,先行课) 选课(学号,课程号,成绩) 请帮忙解释一下下面的语句,谢谢! 1、求没有选修c2课程的学生 select 姓名 from 学生 where not exists (select * from 选课 where 学生.学号=学号 and 课程号='c2'); 2、查询选修了全部课程的学生的姓名 select 姓名 from 学生 where not exists (select * from 课程 where not exists (select * from 选课 where 学生.学号=学号 and 课程.课程号=课程号)); 3、求至少选修了学号为“s2”的学生所选修的全部课程的学生学号和姓名 select 学号,姓名 from 学生 where not exists(select * from 选课 选课1 where 选课1.学号='s2' and not exists (select * from 选课 选课2 where 学生.学号=选课2.学号 and 选课2.课程号=选课1.课程号)
in和not in类似全表扫描,效率低,一般应该用 exist和not exist代替。
not exist也需要遍历整个表吧? 不过exist的确比in效率高多了。
exist 会利用索引来检索,而in不用,这就是本质区别
同意waterblue1981(零风)的, 其实是因为In是内驱动,而exist是外驱动的。 如: select ename from emp e where mgr in (select empno from emp where ename = 'KING'); 是先执行select empno from emp where ename = 'KING' 等效于: select e1.ename from emp e1,(select empno from emp where ename = 'KING') e2 where e1.mgr = e2.empno; 而exist不同 select ename from emp e where exists (select 0 from emp where e.mgr = empno and ename = 'KING'); 其执行类似于下面的pl/sql: set serveroutput on; declare l_count integer; begin for e in (select mgr,ename from emp) loop select count(*) into l_count from emp where e.mgr = empno and ename = 'KING'; if l_count != 0 then dbms_output.put_line(e.ename); end if; end loop; end; 这样用exists话就可以使用索引。数据量大一点的时候就体现出效率。 但不能说exist就比in好。 如果select 0 from emp where e.mgr = empno and ename = 'KING'的数据量很少,还是in效率更高。
Exists --检索到满足条件即退出NOT EXISTS --检索到不满足条件即退出
改成exist语句可以这样的
select * from tab1 where exists(select 1 from tab2 where tab1.col1=tab2.col2)
如果表tab2中的col2有索引的话就能提高效率.而第一条语句中用不到tab2中的索引
学生(学号,姓名,年龄,所在系)
课程(课程号,课程名,先行课)
选课(学号,课程号,成绩)
请帮忙解释一下下面的语句,谢谢!
1、求没有选修c2课程的学生
select 姓名 from 学生
where not exists (select * from 选课 where 学生.学号=学号 and 课程号='c2');
2、查询选修了全部课程的学生的姓名
select 姓名 from 学生
where not exists (select * from 课程 where not exists
(select * from 选课 where 学生.学号=学号 and 课程.课程号=课程号));
3、求至少选修了学号为“s2”的学生所选修的全部课程的学生学号和姓名
select 学号,姓名 from 学生
where not exists(select * from 选课 选课1 where 选课1.学号='s2' and not exists
(select * from 选课 选课2 where 学生.学号=选课2.学号 and 选课2.课程号=选课1.课程号)
不过exist的确比in效率高多了。
其实是因为In是内驱动,而exist是外驱动的。
如:
select ename
from emp e
where mgr in (select empno from emp where ename = 'KING');
是先执行select empno from emp where ename = 'KING'
等效于:
select e1.ename from emp e1,(select empno from emp where ename = 'KING') e2
where e1.mgr = e2.empno;
而exist不同
select ename from emp e
where exists (select 0 from emp where e.mgr = empno and ename = 'KING');
其执行类似于下面的pl/sql:
set serveroutput on;
declare
l_count integer;
begin
for e in (select mgr,ename from emp) loop
select count(*) into l_count from emp
where e.mgr = empno and ename = 'KING';
if l_count != 0 then
dbms_output.put_line(e.ename);
end if;
end loop;
end;
这样用exists话就可以使用索引。数据量大一点的时候就体现出效率。
但不能说exist就比in好。
如果select 0 from emp where e.mgr = empno and ename = 'KING'的数据量很少,还是in效率更高。