阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Oracle子查询相关内容(包含TOP-N查询和分页查询)

86次阅读
没有评论

共计 2600 个字符,预计需要花费 7 分钟才能阅读完成。

本节介绍 Oracle 子查询的相关内容:

实例用到的数据为 oracle 中 scott 用户下的 emp 员工表,dept 部门表,数据如下:

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

一、子查询

1、概念:嵌入在一个查询中的另一个查询语句,也就是说一个查询作为另一个查询的条件,这个查询称为子查询。

那么可以使用子查询的位置有 select 后面、from 后面、where 后面以及 having 后面。

2、分类:(1)单行子查询:查询结果只返回一行数据

(2)多行子查询:查询结果返回多行数据,多行子查询的操作符有 IN,ALL,ANY, 具体用法实例中说明。

3、示例说明:

 Example1:查找每个部门的员工数量:

select deptno,dname,(select count(*) from emp e where e.deptno=d.deptno) amount from dept d;

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

此处子查询位于 select 后面,是每个部门的员工总人数。

Example2: 查找工资大于部门平均工资的员工

select ename,sal,e.deptno from emp e,(select deptno,avg(sal) avgsal from emp group by deptno) m
where e.deptno=m.deptno and e.sal>m.avgsal;

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

此处子查询位于 from 后面,是每个部门的平均工资,将这个结果看做一张新表 m,再加上查询条件即可。

Example3:查找和 scott 相同职位的员工信息

select * from emp where job=(select job from emp where ename=’SCOTT’);

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

此处子查询位于 where 条件中,是和 scott 员工一样的职位。

Example4: 查询部门平均工资大于 30 号部门最高工资的部门信息。

select deptno,avg(sal) from emp group by deptno having avg(sal)>(select max(sal) from emp where deptno=30);

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

此处子查询位于 having 子句中,是 30 号部门的最高工资。

Example5: 查询部门是开发部或销售部的员工信息

select * from emp where deptno in(select deptno from dept where dname=’RESEARCH’ or dname=’SALES’);

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

此处用到了多行子查询的 IN 操作符用来获取 RESEARCH 和 SALES 部门的部门号,用来限制一个范围。

Example6: 获取工资大于 30 号部门所有员工工资的信息。

select ename,sal,deptno from emp where sal>all(select sal from emp where deptno=30);

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

此处用到了多行子查询中的 ALL 操作符,用于获取 30 号部门的所有工资信息,这里 all 起的主要作用是为了获得 30 号部门的最大工资,大于所有的意思就是大于最大的即可。

Example7: 获取工资大于 30 号部门任意员工工资的信息。

select ename,sal,deptno from emp where sal>any(select sal from emp where deptno=30);

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

此处用到了多行子查询中的 any 操作符,用于获取 30 号部门的工资信息,这里 any 的作用和 all 不同,主要取最小工资,任意就是说大于这些工资里面任意一个也就是大于最小的工资即可。

 二、oracle 中 TOP- N 查询:

概念:用于获取一个查询中的前 N 条记录,需要借助 rownum 伪列来实现,rownum 伪列,oracle 为每个查询自动生成的伪列,物理上并不存在,查询中经常涉及多个表,但每个查询只有一列伪列。

Example: 查找部门号为 20 和 30 的工资最高的 5 个员工信息

select * from (select * from emp where deptno in(20,30) order by sal desc) where rownum<=5;

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

这里在 from 后加了一个子查询,那么有个问题出现了,为什么这里不直接写而是要引入一个子查询呢,先来看看不加的结果:

select * from emp e where e.deptno in(20,30) and rownum<=5 order by e.sal desc;

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

很明显 3000 才是最高的工资,那是什么原因导致了这样的结果呢?是因为 oracle 中对 select 查询语句的执行顺序是先 where 条件后 order by 排序 ,也就是说先取了 5 行在对这 5 行进行排序,而正确的顺序应该是所有 20,30 部门的员工工资先进行排序在取 5 行

 三、Oracle 分页查询的应用:

 概念:分页查询,顾名思义,控制查询结果的范围,得到我们想要的部分数据。

Example: 获取员工表中 20,30 部门按工资降序以后的第 4 页也就是第 7,8 两条数据

select * from (select rownum rowline,emp1.* from (select * from emp where deptno in (20,30)
order by sal) emp1 where rownum<=10) emp2 where emp2.rowline>=7 and emp2.rowline<=8;

Oracle 子查询相关内容 (包含 TOP- N 查询和分页查询)

这里或许稍微有点复杂,首先为什么不这样写

select * from (select * from emp where deptno in(20,30) order by sal desc) where rownum>=7 and rownum<=8;

这个查询永远也不会有数据生成,为什么呢,因为当内层查询产生第一条记录时,oracle 为其伪列赋值 rownum=1,

外层查询判 rownum>=7 and rownum<= 8 不符合条件去除记录,当第二条记录产生时,oracle 仍然会为其伪列赋值 rownum=1,

外层判断仍然不会通过,这样无论内层查询产生多少数据都会因为外层查询的条件不符合记录而流失数据。

而想要避免这样的情况发生,就需要将伪列当成一个查询中的字段,将它不在看做“伪列”,而是真正的一个字段,

这样就需要在外面在嵌套一层查询将伪列做成一个物理上存在的字段,而最后我们只需要将外层查询的条件改为内层查询中“真实”存在的伪列即可。

子查询的相关内容总结完毕,有不明处请多多指教。

更多 Oracle 相关信息见 Oracle 专题页面 https://www.linuxidc.com/topicnews.aspx?tid=12

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计2600字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中