单行子查询
select * from emp where sal > (selectsal from emp where empno = 7566);
子查询空值/多值问题
如果子查询未返回任何行,则主查询也不会返回任何结果
(空值)select * from emp where sal > (select sal from emp where empno =8888);
如果子查询返回单行结果,则为单行子查询,可以在主查询中对其使用相应的单行记录比较运算符
(正常)select * from emp where sal > (select sal from emp where empno =7566);
如果子查询返回多行结果,则为多行子查询,此时不允许对其使用单行记录比较运算符
(多值)select * from emp where sal > (select avg(sal) from emp group by
deptno);//非法
多行子查询
select * from emp where sal >any(select avg(sal) from emp group by deptno);
select * from emp where sal >all(select avg(sal) from emp group by deptno);
select * from emp where job in (select job from emp where ename= 'MARTIN' or ename = 'SMITH');
TopN 查询
select * from emp where rownum=1 orrownum=2;
分页查询
select * from (select rownum no,e.*from (select * from emp order by saldesc) e where rownum<=5 ) where no>=3;
select * from (select rownum no,e.* from(select * from emp order by sal desc) e) where no>=3 and no<=5;
exists
EXISTS 的执行流程
select * from t1 where exists ( selectnull from t2 where y = x )
可以理解为:
for x in ( select * from t1 )
loop
if ( exists ( select null from t2 where y = x.x )
then
OUTPUT THE RECORD
end if
end loop
对于 in 和 exists 的性能区别:
如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用 in,反之如果外层的主
查询记录较少,子查询中的表大,又有索引时使用 exists。
其实我们区分 in 和 exists 主要是造成了驱动顺序的改变(这是性能变化的关键),如果是 exists,
那么以外层表为驱动表,先被访问,如果是 IN,那么先执行子查询,所以我们会以驱动表的快速返
回为目标,那么就会考虑到索引及结果集的关系了
另外 IN 是不对 NULL 进行处理
如:
select 1 from dual where null in (0,1,2,null)
为空
网友评论