分享好友 最新资讯首页 最新资讯分类 切换频道
oracle部门总工资的函数,Oracle分析函数
2024-12-30 01:24

分析函数,通过对SQL语言进行扩展。

例子:将计算scott方案中emp表的员工薪资的运行总计,分部门运行总计。

select ename,deptno,sal,SUM(sal) OVER (order by deptno,ename)运行总计,SUM(sal) OVER(PARTITION by deptno order by ename)分部门运行总计,ROW_NUMBER()OVER(PARTITION by deptno order by ename) 序列  from emp where deptno IN(10,20) order by deptno,ename

1.sum和over是分析函数的语句,sum是一个分析函数,尽管这个函数与分组函数中的sum同名,但是在与over关键字连用时,sum被标识为分析函数。

2.order by 是可选的关键字,有些函数需要

3.PARTTITION BY 是可选的分区子句

4.row_number()函数根据排序标准,返回每个组的行编号,row_number()返回的行号根据分区与排序的不同而不同。

分析函数结构

一.分析函数名

oracle提供了26个分析函数 分为五大类

1.等级函数:用于前N种查询,比如ROW_NUMBER函数,RANK,DENSE_RANK等

select o.deptno,o.job,sum(o.sal) 部门职级汇总,rank()over(order by sum(o.sal) desc) 薪资等级,dense_rank() over(order by sum(o.sal)desc)dense_rank 排名,row_number() over (partition by o.deptno order by sum(o.sal) desc) 分组行号,sum(sum(o.sal)) over (partition by o.deptno order by o.job)部门薪资运行总计from emp o where deptno in (10,20,30) and job is not null group by o.deptno,o.job;

可以看到rank和dense_rank对记录进行了排名。

2.开窗函数:用来计算行的累计值,这些函数与分组函数同名,比如sum count avg等

sum(t.sal) over (order by t.deptno,t.ename) running_total

3.制表函数:与开窗函数相似,制表函数也允许对一个结果集执行多种聚合运算,比如min,max sum count等,与窗口函数不同的是,制表函数不能指定一个本地窗口,因此总是在整个分区或整个组上产生相同的结果

sum(t.sal) over()running_total2

可以看到比开窗函数基础上少了order by子句

4.LAG和LEAD函数:允许在结果集中向前或向后检索值,如果要避免数据的自连接,它们是非常有用的

5.其他统计函数:例如var_pop  var_samp  和stdev_pop及线性的衰减函数等这些函数计算任何未排序分区的统计值。

二.分区子句

分区子句使用partition by关键字,用来简单的结果集分为N组。

select deptno,ename,empno row_number () over(partition by deptno order by empno) 分组行号 from emp where deptno in (10,20,30);

当指定了partition by 关键字时 行号在切换到不同的deptno时 将自动从1开始重新分配

三.排序子句

order by 子句用于指定分组中数据的排序方式,排序方式会明显地影响任何分析函数的结果。

分析函数总是按order by对行排序,然而,分析函数中的order by子句只能对各个分组进行排序,而不能保证查询结果有序。要保证最后的查询结果有序,可以使用查询的order by子句

四.开窗子句

开窗子句必须定义在order by子句的后面,用来定义一个变化或固定的数据窗口方法,分析函数将对这些数据进行操作。在分区内部基于任何的变化或固定的窗口中,通过窗口让分析函数来计算其值

例如统计各部门的工资小计及所有部门的薪资总计

select deptno,sum(sal) 部门薪资小计,sum(sum(sal))over(order by deptno rows between unbounded preceding and unbounded following )部门总计 from emp group by deptno;

rows between unbounded preceding and unbounded following这个子句是oracle提供的开窗子句,是指将计算第一条到最后一条的记录,也就是表中所有的记录

分析函数列表

1.COUNT函数

统计各分区中各组的行数

select empno,ename count(*) over (partition by deptno order by empno)条数小记 from emp;

Distinct用来统计唯一值,仅在分区子句中使用,不能在order by 和开窗子句中使用

统计与当前员工工资的差异在50~150之间的其他员工的记录

select empno,ename,sal,count(*)over(order by sal range between 50 preceding and 150 following)薪水差异个数 from emp;

range between来判断sal值是否在50到150之间

2.sum函数

用来汇总分区中的记录

3.avg函数

例如要计算emp表中每个部门的平均薪资表。

select deptno,empno,ename,sal,avg(sal) over (partition by deptno order by deptno)avg_sal from emp;

4.min和max函数

用来计算分区中的最小值或最大值,这两个函数的声明语法

查询同一部门中雇佣日期比当前员工早的员工的最低薪水与最高薪水

select deptno,empno,ename,hiredata,sal,min(sal) over(partition by deptno order by hiredate rang unbounded preceding)最低薪水 max(sal) over(partition by deptno order by hiredate range unbounded preceding )最高薪水 from emp;

5.rank,dense_rank和row_number函数

rank和dense_rank都用来记录编号,根据order by子句中表达式的值,计算它们与其他行的相对位置,每一行赋一个数字序号,形成一个从1开始的序列,将相同的值得到同样的数字序号。不同之处在于rank将相同的行分配同样的序号之后,后面的行将跳跃,比如如果两行序数为1,则没有序数2,直接跳到序数3,而dense_rank则没有任何跳跃值。

row_number也是从1开始用来为记录分配行号,与rank和dense_rank不同的是,不管是否存在重复行,分区类的序列值始终递增。

select deptno,ename,sal,mgr

rank() over(order by deptno) rank 结果

dense_rank() over(order by deptno)dense_rank 结果

row_number()over(order by deptno)row_number 结果 from

emp where deptno in (10,20,30) and mgr is not null order by deptno;

6.FIRST 和LAST 函数

first和last 取dense_rank返回的集合中取出排在第一的行和最后一行。

下面的语句使用first和last返回emp表中具有最高提成的员工薪水和具有最低提成的员工薪水

select deptno

min(sal)keep(dense_rank first order by comm)最低提成薪水

max(sal)keep (dense_rank last order by comm)最高提成薪水

from emp where deptno in(10,20,30) group by deptno;

显示最高提成和最低提成员工的薪资

7.first_value和last_value 函数

分别用来返回over子句中查询出来的第一条记录和最后一条记录。

获取部门中第一条薪资记录值和最后一条记录值

select deptno,empno,sal

first_value(sal) over (partition by deptno order by empno)"第一个值"

last_value(sal)over(partition by deptno order by empno) "最后一个值"

from emp where deptno in(10,20);

8.lag和lead函数

lag的功能是返回指定列col前n1行的值(如果前n1行已经超出比照范围,则返回n2,如果不指定n2则默认返回null),如果不指定n1,其默认值为1;lead函数与此相反,返回指定列coll后面的n1行的值。

使用lag和lead函数查找当前雇佣的前一个雇员的薪水和后一个雇员的薪水

select ename,hiredate,sal,deptno

lag(sal,1,0)over(order by hiredate)as 前一个雇员薪水

lead(sal,1,0)over(order by hiredate)as 后一个雇员薪水

from emp where deptno=30;

可以看到由于第一条记录的前一条不存在,因此前一个雇员的薪水返回0;最后一条记录由于不存在后一条记录,因此后一个雇员的薪水也为0

分析函数使用示例

1.记录排名

人事部需要对emp表中各个不同部门的员工薪资总计进行排名,可以使用如下

select deptno ,empno,sum(sal) dept_sales

rank()over(partition by deptno order by sum(sal)

dese nulls last)薪资排名_跳号

dense_rank()over(partition by deptno order by sum(sal)desc nulls last)薪资排名_同级同号

row_number()over(partition by deptno order by sum(sal)desc nulls last)薪资排名_不跳号

from emp group by deptno,empno,ename;

语句中使用nulls last  使得null值排在分区的最后。

2.首尾记录查询

查询出员工薪资中最高和最低薪资的员工编号,听起来需要两个分组查询,实际上使用分组函数后,一行语句就可以得到想要的结果。

select min(empno)keep(dense_rank first order by sum(sal)desc  nulls last)薪资排名首位

min(empno)keep(dense_rank last order by sum(sal) desc nulls last) 薪资排名尾位

from emp where sal is not null and deptno is not null group by empno;

keep用于告诉oracle保存符合keep后面语句条件的记录。

3.前后排名查询

查询部门的员工薪资排名在前2位的员工列表

select deptno,empno,ename,dept_sales,薪资排名 from

(

select deptno,empno,ename,sum(sal)dept_salse

rank()over(partition by deptno order by sum(sal)

desc nulls last)薪资排名

from emp where deptno is not null group by deptno,empno,ename—)where 薪资排名<=2;

上述查询结果作为一个内联视图,通过对内联视图返回的排名进行排序,很轻松就得到了部门分组中的薪资的前2名。当然如果要获取排名在后2位的员工,只需要order by 子句中将排序进行反转,按正向进行排序即可

select deptno,empno,ename,dept_sales,薪资排名 from

(

select deptno,empno,ename,sum(sal)dept_sales

rank()over(aprtition by deptno order by sum(sal) nulls last)薪资排名

from emp where deptno is not null group by deptno,empno,ename)

where 薪资排名<=2;

4.层次查询

所为查询,是指按比率得到结果数,比如想查询薪资排名在前1/3的员工列表。要查询薪资在前1/3的员工列表

select * from

(

select deptno,empno,ename,sum(sal)dept_sales

NTILE(3)over(partition by deptno

order by sum(sal)nulls last)rank_ratio

from emp where deptno is not null

group by deptno,empno,ename)

where rank ratio=1;

5。范围统计查询

范围查询是分析函数发挥其功能的重点,范围查询是指查询当前记录的前面或后面的记录进行统计。

比如想知道员工史密斯的雇佣日期前10天和后10天新进员工的最高薪资。

select empno,ename,hiredate,sal

MAX(sal)over(order by hiredate rows between 10 preceding and

current row) "前10天入职员工最高薪资"

MAX(sal)over(order by hiredate rows between current row and 10

following)"后10天入职员工最高薪资"

from emp

where deptno in(10,20,30)and sal is not null;

6.相邻记录比较

查询当前员工前一个入职的员工和后一个入职的员工与当前员工的薪资差异

select ename,hiredate,deptno,sal,sal-prev_sal "与前面的差异",sal-next_sal "与后面的差异"

from (select ename,hiredate,sal,deptno

LAG (sal,1,0)over(order by hiredate)as prev_sal

LEAD(sal,1,0)over(order by hiredate)as next_sal

from emp

where deptno is not null and sal is not null);

7.抑制重复

人事部需要随机地提取各部门在1980 1981 和1982年入职的任意一个员工,由于在各个部门中这几个年份入职的员工较多,因此人事部门只是随意地提取一个员工即可,不要求统计提取,可以使用如下的分析查询语句

select *

from (select empno,ename,sal,hiredate

ROW_NUMBER()over(partition by extract

(year from hiredate) order by empno) rn

from emp

where hiredate is not null

and extract (year from hiredate) in (1981,1982,1983))

where rn=1;

8.行列转换查询

select job,empno,ename

row_number()over(partition by job order by ename)rn

from emp

where job is not null;

select max(decode(job'职员',ename,NULL))"职员名称"

max(decode(job'分析人员',ename,NULL))"分析人员名称"

max(decode(job'经理',ename,NULL))"经历名称"

max(decode(job'老板',ename,NULL))"老板名称"

max(decode(job'销售人员',ename,NULL))"销售人员名称"

from(select job,empno,ename,row_number()over (partition by job order by ename)rn from emp where job is not null)x

在PL/SQL中使用分析函数

declare

type refempcur is ref cursor;

empcurrefempcur;

jobname varchar(20);

ename   varchar2(20);

empno   number;

rnint;

begin

open empcur for

select job,empno,ename,row_number () over (partition by job order by ename)rn from emp where job is not null;

loop

exit when empcur%NOTFOUND;

fetch empcur

into jobname,empno,ename,rn;

dbms_output.put_line(jobname || '  '||empno || '  '||ename||'  '||rn);

end loop;

最新文章
Google Trends和Google Insights
Google Trends(谷歌趋势)发布过中文版,是Google推出的一款基于搜索日志分析的应用产品,通过这个工具可以知道某一搜索关键词
AI绘画工具MJ新功能有点东西,小白也能轻松一键换装
先看最终做出来的效果直接来干货吧。Midjourney,下面简称MJ1.局部重绘功能来袭就在前两天,MJ悄咪咪上线了这个被众人期待的新功
AI制冷,守护绿色未来
互联网发展至今,全球已有近44亿网民,我们通过不同的设备连接互联网,享受着在线购物,在线交友等一系列智能生活,而这背后,离
DDos攻击的防御方法
到目前为止,进行DDoS攻击的防御还是比较困难的。首先,这种攻击的特点是它利用了TCP/IP协议的漏洞,除非你不
AI音乐生成将导致音乐作品版权概念的消亡
在这个迅速变化的时代,科技的进步总是令人惊叹。最近AI音乐生成技术的兴起,开始掀起了关于音乐作品版权的讨论。或
ai语音功能是什么 ai语音功能详解?
2、可以帮用户完成生活当中的众多琐事,比如说翻译、打车、酒店、购物、百科百答等等;3、能够进行全场景实时图像搜索,让电视播
CLion和IDEA集成的ai代码助手——通义灵码的使用及其自动代码补全的禁用设置等使用优化
       通义灵码,作为智能编码on助手,可以在进行编码工作时,为你提供行级/函数级实时续写、自然语言生
11、作为服务注册中心,Eureka比Zookeeper好在哪里?  ***
目录 1、什么是微服务? 2、微服务之间是如何通讯的? 3、springcloud 与dubbo有哪些区别?  4、springBoot
AI�˹�����Ʒ�����а���˹�����δ����չ
�˹����ܣ�AI���ǵ���Ƽ�������Ϊ���ֿ��ȵĻ���֮һ�����ż����IJ��Ͻ�����Ӧ�õ