oracle之分析函数 开窗函数,oracle之分析函数over及开窗函数

统计各班成绩第一名的同学信息

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是连续排序,有两个第二名时仍然跟着第三名

二:开窗函数

开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:

1:

over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数

over(partition by deptno)按照部门分区

2:

over(order by salary range between 5 preceding and 5 following)

每行对应的数据窗口是之前行幅度值不超过5,之后行幅度值不超过5

例如:对于以下列

aa

1

2

2

2

3

4

5

6

7

9

SQL>select  sum(aa)over(order by aa range between 2 preceding and 2 following) from A1;

得出的结果是

AA SUM

---------------------- -------------------------------------------------------

1    10

2   14

2   14

2   14

3   18

4   18

5   22

6   18

7   22

9   9

就是说,对于aa=5的一行 ,sum为 5-1<=aa<=5+2 的和

对于aa=2来说 ,sum=1+2+2+2+3+4=14 ;

又如 对于aa=9 ,9-1<=aa<=9+2 只有9一个数,所以sum=9 ;

3:其它:

over(order by salary rows between 2 preceding and 4 following)

每行对应的数据窗口是之前2行,之后4行

4:下面三条语句等效:

over(order by salary rows between unbounded preceding and unbounded following)

每行对应的数据窗口是从第一行到最后一行,等效:

over(order by salary range between unbounded preceding and unbounded following)

等效

over(partition by null)

--

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

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 ...)

lead() over(partition by ... order by ...)

--

--

--

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

1、row_number() over(partition by ... order by ...)

2、rank() over(partition by ... order by ...)

3、dense_rank() over(partition by ... order by ...)

4、count() over(partition by ... order by ...)

5、max() over(partition by ... order by ...)

6、min() over(partition by ... order by ...)

7、sum() over(partition by ... order by ...)

8、avg() over(partition by ... order by ...)

9、first_value() over(partition by ... order by ...)

10、last_value() over(partition by ... order by ...)

11、lag() over(partition by ... order by ...)

12、lead() over(partition by ... order by ...)

关于partition by

这些都是分析函数,好像是8.0以后才有的 row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开时排序)

rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内)

dense_rank()是连续排序,有两个第二名时仍然跟着第三名。

相比之下row_number是没有重复值的 lag(arg1,arg2,arg3):

arg1是从其他行返回的表达式 arg2是希望检索的当前行分区的偏移量。是一个正的偏移量,时一个往回检索以前的行的数目。 arg3是在arg2表示的数目超出了分组的范围时返回的值。

1.

select deptno,row_number() over(partition by deptno order by sal) from

emp order by deptno;

2.

select deptno,rank() over (partition by deptno

order by sal) from emp order by deptno;

3.

select deptno,dense_rank()

over(partition by deptno order by sal) from emp order by deptno;

4.

select

deptno,ename,sal,lag(ename,1,null) over(partition by deptno order by ename) from

emp ord er by deptno;

5.

select deptno,ename,sal,lag(ename,2,'example')

over(partition by deptno order by ename) from em p

order by

deptno;

6.

select deptno, sal,sum(sal) over(partition by deptno) from

emp;--每行记录后都有总计值  select deptno, sum(sal) from emp group by deptno;

7.

求每个部门的平均工资以及每个人与所在部门的工资差额

select deptno,ename,sal ,

round(avg(sal) over(partition by deptno))

as dept_avg_sal,

round(sal-avg(sal) over(partition by deptno)) as

dept_sal_diff

from emp;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值