oracle 子查询详解 in和exists的区别
sql允许多层嵌套,子查询是嵌套在其他查询中的查询。我们可以把子查询当做一张表来看到,即外层语句可以把内嵌的查询结果当做一张表使用。
子查询查询结果有三种情况
不返回查询记录。若子查询不返回记录则主查询也不会有查询记录
查询单行记录。若子查询返回的是单行记录,则在主查询中可以对该单行记录使用比较运算符
查询多行记录。若子查询返回多行记录,则在主查询中不能对该子查询记录使用比较运算符
条件比较
=,!=,<>,<,>,<=,>=,
any,some,all
is null,is not null
between x and y
in(list),not in(list)
exists(sub-query)
like _ ,%,escape ‘\‘ _\% escape ‘\’
子查询常用方法
1、any 即任何一个 ,大都用大于或小于的时候
select * from emp e where e.sal > any(1000,2000,3000); --大于其中其中任何一个
select * from emp e where e.sal > any(select s.losal from salgrade s );--大于其中其中任何一个
2、some 一些,和any的用法相同,不过some大都用在 等于的时候
select * from emp e where e.sal = some(1000,2000,3000);--等于其中其中任何一个
select * from emp e where e.sal = some(select s.losal from salgrade s );--等于其中其中任何一个
3、all 所有,即同时满足所有的
select * from emp e where e.sal > all(1000,2000,3000);--同时大于所有的
select * from emp e where e.sal > all(select s.losal from salgrade s );--同时大于所有的
4、in
select * from emp e where e.deptno in (10,20);
等同于 select * from emp e where e.deptno='10' or e.deptno='20';
所以当主表查询数据量大,子查询数据量少的情况使用in
5、exists
exists(sub-query 只要这里面能返回一条结果,整个表达式就为true)
select e1.* from emp e1 where exists( select 1 from dept d1 where (d1.deptno=10 or d1.deptno=20) and d1.deptno=e1.deptno);
当主查询数据量小,子查询数据量大的情况使用exists
In和exists的区别
执行效率上的比较
比如Select * from T1 where x in ( select y from T2 )
执行的过程相当于:
select *
from t1, ( select distinct y from t2 ) t2
where t1.x = t2.y1 or t1.x = t2.y2 ....;
所以当子查询数据量较大时执行效率会降低
select * from t1 where exists ( select null 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
表 T1 不可避免的要被完全扫描一遍
in 是把外表和内表作hash join,而exists是对外表作loop,每次loop再对内表进行查询。
如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in,反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。 其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 另外IN是不对NULL进行处理
最新文章
- JavaScript语言精粹--Function,类,this,对象
- php大力力 [048节] php一点支付开发资料,很散
- linux 安装beyond compare
- JavaScript的“闭包”到底是什么(2)
- Qt之开机自启动
- 有没有安全的工作?(99条评论)——结论是没有一劳永逸的工作,要终身学习,IT业刚出道和老手还是有区别的(同样对于新技术,薪资可能是个问题)
- Java精选笔试题
- UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)
- 城市安全风险管理项目Postmortem结果
- CF877F
- Python统计词频的几种方式
- 利用div绘制细线居中
- 阶段01Java基础day26反射
- sqlite当天时间的23:59:59
- 算法之Python实现 - 003 : 换钱的方法数
- Oracle主从同步、双向同步的配置
- Python Every Class Needs a __repr__
- learning at command AT+CSQ
- docker-compose 管理多个docker容器实例
- 实现接口时@Override注解问题
热门文章
- 我的Android进阶之旅------>android Button上面的英文字符串自动大写的问题解决
- MySQL(多表的表记录的查询)
- DRF(3) - 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件
- is和==的区别以及编码、解码
- eclipse或Myeclipse中web项目没有run on server时怎么办?
- Ubuntu Linux下通过代理(proxy)使用git上github.com
- TypeScript学习笔记—数据类型
- webdriver的API
- 初识JS 基本语法.基本运算符
- WCF RIA SERVICE相关技术