分析函数,通过对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;

end;

oracle部门总工资的函数,Oracle分析函数相关推荐

  1. 查询各部门总工资最高的部门中工资最高的员工姓名,工资,所在区域,部门

    sql 表 1. staff表(.sql文件) SET FOREIGN_KEY_CHECKS=0; – Table structure for staff DROP TABLE IF EXISTS s ...

  2. oracle普通用户使用dbms函数,oracle使用DBMS_SCHEDULER调度作业

    dbms_scheduler包的功能比dbms_job包强大很多,但是很多初学者直接被它的复杂性吓跑了,跟着我,只需几分钟就会用了. 三个概念 大多数人看到这个包里的函数和函数里众多的参数,就开始晕菜 ...

  3. oracle中or的替函数,Oracle常用内置Or自定义函数-SQL宝典

    一 .函数使用说明 1.NLSSORT(列名,排序规则) 在oracle9i中新增了按照拼音.部首.笔画排序功能.设置NLS_SORT值 SCHINESE_RADICAL_M   按照部首(第一顺序) ...

  4. oracle一行拆多行函数,Oracle 实现多行转换成一行 使用oracle 10g collect函数

    在Oracle 10g中,新增加了一个聚合函数 collect:Takes a column of any type and creates a nested table of the input t ...

  5. oracle中where中使用函数,Oracle 尽量避免在 SQL语句的WHERE子句中使用函数

    -- Start 在 WHERE 子句中应该尽量避免在列上使用函数,因为这样做会使该列上的索引失效,影响SQL 语句的性能.即使该列上没有索引,也应该避免在列上使用函数.考虑下面的情况: CREATE ...

  6. oracle中随机整数的函数,Oracle随机函数的用法

    简单得说,Oracle 取随机数,大多是通过调用dbms_random包产生,通过dbms_random包产生随机数的方法大致有下面4种: 1.dbms_random.normal 这个函数不带参数, ...

  7. oracle中101向上取整,oracle向上取整的函数 oracle除数取整

    excel中取整函数是如何实现的? 让我们看看Excel的舍入问题 !分别使用: 1,int(A1),round directly 2,A1 mod(A1,1),mod(A1,1)是获取小数点的方法 ...

  8. oracle与join相反的函数,ORACLE JOIN 与 +

    JOIN: 1. Natural join:自然连接,ORACLE 自动根据两表中类似的列进行连接: 2. Outer join:Left outer join.Right outer join.Fu ...

  9. oracle日期转数值的函数,oracle数据库内置函数之数值函数、字符函数、日期函数、转换函数及其在查询语句中的运用...

    数值函数: 1.四舍五入函数round() from dual:一行一列组成 select round(23.4) from dual;--默认不写m表示m为0 select round(23.45, ...

最新文章

  1. 开机BIOS语言(转载)
  2. 翻窗户消失的百岁老人/百岁老人跷家去 中文字幕
  3. 在Makefile中的 .PHONY 是做什么的?
  4. Arraylist、HashSet去重复 treeSet排列实现方法 HashMap遍历取值
  5. Winform中实现ZedGraph曲线图的图像复制到剪切板、打印预览、获取图片并保存、另存为的功能
  6. OpenCV透视校正perspective correction的实例(附完整代码)
  7. Linux的Nginx六:源码|安装
  8. 阿呆做网站(1)--基本功能
  9. SpringBoot 下 Mybatis 的缓存
  10. opengl es3.0游戏开发学习笔记2--绘制地月星系
  11. endnote初始化数据库支持_考前复习必备MySQL数据库(关系型数据库管理系统)
  12. COOLPAD F608刷机过程
  13. 电路分析之正弦稳态电路的仿真与研究
  14. Firemonkey下使用StyleBook的一些经验
  15. 使用IK中文分词器做敏感词过滤
  16. 【C++】【记录自己的自学过程】用纯C++实现模拟银行注册 存款 取款 贷款 升级账户 等服务。主要用的内容包括多态,封装。
  17. The YARN Timeline Server
  18. H264码流中NALU sps pps IDR帧的理解
  19. 手机录像出现arn无响应
  20. 微信订阅号如何开通付费功能

热门文章

  1. hdu 5234-三维背包
  2. linux下drcom无法上网,安装drcom出现问题
  3. 平安新一贷怎么被拒了及原因是什么?你都知道吗?
  4. 调研 FlinkSql功能测试及实战演练
  5. Asp.Net Core3.1-集成Hangfire
  6. N张图片合成一个最终图片(像素图片)
  7. 苹果电脑mysql安装流程_mac系统下安装mysql步骤
  8. 二阶偏导相等的一个充分条件
  9. C++11更新内容(2)--完美转发--默认移动构造/移动赋值--1116
  10. 微信小程序加签验签(wxapp_rsa,jsencrypt)和egg搭建的后端交互(jsrsasign,node_rsa)最全!!!