oracle开窗函数over()

来源:互联网 发布:mac版迅雷下载速度为0 编辑:程序博客网 时间:2024/04/29 03:36


1. 先说概念

oracle 从8.1.6开始提供分析函数。分析函数用于计算基于组(partition)的聚合值,但与聚合函数不同的是,分析函数可以返回基于组的多行数据,而聚合函数只能返回基于group by条件的一行数据。

2.再说应用场景

JRN_NO

流水号

Varchar2(32)

USR_NO

内部用户号

Varchar2(20)

MBL_NO

手机号

Varchar2(12)

SYS_DT

系统日期

Varchar2(8)

SYS_TM

系统时间

Varchar2(6)

以内部用户号+手机号为维度,以系统时间为条件查出最近一笔流水的流水号。


3.讨论方案

如果用max()函数的话只能拿USR_NO和MBL_NO做group by,即:

SELECT USR_NO, MBL_NO,max(SYS_DT || SYS_TM) time  FROM MPL_JRNYJY group by usr_no, mbl_no ORDER BY time DESC
此时查询结果没有JRN_NO,如果要加入JRN_NO的话就要拿JRN_NO,USR_NO,MBL_NO做group by,这就导致结果不正确。

此时就可以用over()函数以USR_NO,MBL_NO做partition by分区,拿出每个分区中最新的一条即可。


4. 语法

over(partition by 分区条件 order by 排序条件 rows between );

over()需要其他函数配合,结合函数有如下:

row_num()over(...) ---> 返回分组内行号

rank()over(...) --->返回分组内排名(跳跃排序:1、2并列时,第三条结果为4)

dense_rank()over(...)    --->返回分组内排名(连续排序:1、2并列时第三条结果为3)

sum()over(...) --->返回分组内值之和


5.结果
因业务场景要求是“一笔”,即使有同一时刻的流水也只取其中一笔。所以我采用row_num()over() 。如果要求查出并列多笔的话可以采用rank()over()或者

select *  from (select jrn_no,               usr_no,               mbl_no,               SYS_DT,               SYS_TM,               row_number() over(partition by usr_no, mbl_no order by SYS_DT || SYS_TM desc) a          from MPL_JRNYJY) where a = '1'



原创粉丝点击