over()分析函数

这个函数长这个样子:OVER(PARTITION BY… ORDER BY…)

顾名思义,PARTITION 中文是分割的意思,ORDER 是排序的意思,所以翻译一下就是先把一组数据按照制定的字段进行分割成各种组,然后组内按照某个字段排序。
在使用 row_number() over()函数时候,over()里头的分组以及排序的执行晚于 where 、group by、 早于order by 的执行。
伪列ROWNUM

常用的分析函数如下所列:

 - row_number() over(partition by ... order by ...)		--分组排序
 - rank() over(partition by ... order by ...)		--分组排序
 - dense_rank() over(partition by ... order by ...)		--分组排序
 - count() over(partition by ... order by ...)		--分组计数
 - max() over(partition by ... order by ...) 		--分组取最大值
 - min() over(partition by    ... order by ...)		--分组取最小值
 - sum() over(partition by ... order by ...)		--分组求和
 - avg() over(partition by ... order by ...)		--分组取平均值
 - first_value() over(partition by ... order by ...)		--取分组第一条
 - last_value() over(partition by ... order by ...)			--取分组最后一条
 - lag() over(partition by ... order by ...)		--取出同一字段的前N行的数据
 - lead() over(partition by ... order by ...)		--取出同一字段的前N行的数据

 1,辨析分组排序:伪列rownum()、row_number() over()、rank() over()、dense_rank() over
创建表:

create table testdata (
id int,ename varchar2(20),sal number(10),code varchar2(20));

插入数据:

insert into testdata values(1,'a001',100,'aaaaa');
insert into testdata values(2,'a001',500,'aaaaa');
insert into testdata values(3,'a001',200,'bbbbb');
insert into testdata values(4,'a002',400,'ccccc');
insert into testdata values(5,'a002',300,'aaaaa');
insert into testdata values(6,'a003',200,'ccccc');
insert into testdata values(7,'a003',800,'ddddd');
insert into testdata values(8,'a002',400,'ccccc');
insert into testdata values(9,'a003',100,'aaaaa');
insert into testdata values(10,'a003',200,'ddddd');
commit;

 数据测试:

select id,ename,sal,code,rownum ,--伪列
	row_number() over(partition by ename order by sal) row_number,
	rank() over(partition by ename order by sal) rank_over,
	dense_rank() over(partition by ename order by sal) dense_rank
from testdata

结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200310224233461.png
注意:
–id列为编号列
–伪劣rownum为数据插入时自动生成的列
–row_number() 按分组排序方式依次生成序号,有两个第一名时,只取一个
–rank()是跳跃排序,有两个第二名时接下来就是第四名
–dense_rank()是连续排序,有两个第二名时仍然跟着第三名

2,分组运算

- count() over() 分组计数

select id ,ename, sal ,code ,
	count(1) over(partition by code ) count_over,	--计数汇总
	count(1) over(partition by code order by id) count_order_by		--分步计数
from testdata;

显示结果:
在这里插入图片描述

max() over() 、min() over() 分组取最大值、最小值 

select id ,ename, sal ,code ,
	max(sal) over(partition by code ) max_over,		--取分组内数据的最大值
	max(sal) over(partition by code order by sal asc) max_order_by	--分步取最大值
from testdata;
  • sum() over()分组求和
select id ,ename, sal ,code ,
	sum(sal) over(partition by ename ) sum_over,	--分组数据求和
	sum(sal) over(partition by ename order by id) sum_order_by	--分步求和
from testdata;

 显示结果:
在这里插入图片描述

  • avg() over() 分组取平均 
select id ,ename, sal ,code ,
	avg(sal) over(partition by code ) avg_over,		--分组内数据平均
	avg(sal) over(partition by code order by id) avg_order_by	--分步取平均
from testdata;

 显示结果:
在这里插入图片描述

3,lag()和lead()统计函数可以在一次查询中取出同一字段的前N行的数据和后N行的值。这种操作可以使用对相同表的表连接来实现,不过使用LAG和 LEAD有更高的效率。Lag函数为Lag(exp,N,defval),defval是当该函数无值可用的情况下返回的值。Lead函数的用法类似。

select id ,ename, sal ,code ,
	lead(sal,1,0) over(partition by ename order by sal asc) leads,
	lag(sal,1,0) over(partition by ename order by sal asc) lags
from testdata;

 显示结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/202003102319063.pn

 

一:分析函数over
Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是对于每个组返回多行,而聚合函数对于每个组只返回一行。

下面通过几个例子来说明其应用。

1、统计某商店的营业额。
date sale
1 20
2 15
3 14
4 18
5 30

规则:按天统计:每天都统计前面几天的总额,得到的结果:

在这里插入图片描述 

 select day,sale,sum(sale) over (order by day asc ) as 连续求和,sum(sale) over() as 总和 from t_temp;
2、统计各班成绩第一名的同学信息
NAME CLASS S
----- ----- ----------------------
fda 1 80
ffd 1 78
dss 1 95
cfe 2 74
gds 2 92
gf 3 99
ddd 3 99
adf 3 45
asdf 3 55

3dd     3      78

select * from
(
select name,class,s,rank()over(partition by class order by s desc) mm from t2
)
where mm=1
得到结果:
NAME CLASS S MM
----- ----- ---------------------- ----------------------
dss 1 95 1
gds 2 92 1
gf 3 99 1
ddd 3 99 1
注意:
1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果
2.rank()和dense_rank()的区别是:
–rank()是跳跃排序,有两个第二名时接下来就是第四名
–dense_rank()l是连续排序,有两个第二名时仍然跟着第三名

3.分类统计 (并显示信息)
A B C
– -- ----------------------
m a 2
n a 3
m a 2
n b 2
n b 1
x b 3
x b 2
x b 4
h b 3
select a,c,sum©over(partition by a) from t2
得到结果:
A B C SUM©OVER(PARTITIONBYA)

h b 3 3
m a 2 4
m a 2 4
n a 3 6
n b 2 6
n b 1 6
x b 3 9
x b 2 9
x b 4 9
如果用sum,group by 则只能得到
A SUM©

h 3
m 4
n 6
x 9

无法得到B列值
————————————————

原文链接:
https://blog.csdn.net/guobinhui/article/details/80965191
https://blog.csdn.net/fygkchina/article/details/80521550
https://blog.csdn.net/fxz_2010/article/details/83907152

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值