oracle开窗函数over()


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'



你可能感兴趣的:(Oracle)