将Oracle SQL与仅选择权限一起使用时,我需要ROW_NUMBER根据条件提供输出.使用游标或循环这很容易,但目前我必须只使用SQL来执行此任务.
我一直在修补一个row_number() over我认为是正确的方法的条款,但我现在被困住了.
我目前的代码 - 或者至少是它的代理:
WITH MYTABLE (FK_ID,FK_NAME,PK_ID,BIN_FLAG,MONTH,YEAR)AS (
SELECT 10000,'VARCHAR DESCRIPTION',75057,1,1,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,1,2,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,1,3,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,4,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,1,5,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,6,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,7,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,1,8,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,9,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,10,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,1,11,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,12,2016 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,1,2017 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,2,2017 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,3,2017 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,4,2017 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,5,2017 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,6,2017 FROM DUAL
UNION SELECT 10000,'VARCHAR DESCRIPTION',75057,0,7,2017 FROM DUAL
)
SELECT
FK_ID
, FK_NAME
, PK_ID
, BIN_FLAG
, ROW_NUMBER() OVER (PARTITION BY FK_ID,PK_ID,BIN_FLAG ORDER BY YEAR,MONTH,FK_ID,PK_ID ASC) NEEDED_CALC
, MONTH
, YEAR
FROM MYTABLE
ORDER BY FK_ID,PK_ID,YEAR,MONTH
Run Code Online (Sandbox Code Playgroud)
这将返回一个如下所示的数据集:
FK_ID FK_NAME PK_ID BIN_FLAG NEEDED_CALC MONTH YEAR
10000 VARCHAR DESCRIPTION 75057 1 1 1 2016
10000 VARCHAR DESCRIPTION 75057 1 2 2 2016
10000 VARCHAR DESCRIPTION 75057 1 3 3 2016
10000 VARCHAR DESCRIPTION 75057 0 1 4 2016
10000 VARCHAR DESCRIPTION 75057 1 4 5 2016
10000 VARCHAR DESCRIPTION 75057 0 2 6 2016
10000 VARCHAR DESCRIPTION 75057 0 3 7 2016
10000 VARCHAR DESCRIPTION 75057 1 5 8 2016
10000 VARCHAR DESCRIPTION 75057 0 4 9 2016
10000 VARCHAR DESCRIPTION 75057 0 5 10 2016
10000 VARCHAR DESCRIPTION 75057 1 6 11 2016
10000 VARCHAR DESCRIPTION 75057 0 6 12 2016
10000 VARCHAR DESCRIPTION 75057 0 7 1 2017
10000 VARCHAR DESCRIPTION 75057 0 8 2 2017
10000 VARCHAR DESCRIPTION 75057 0 9 3 2017
10000 VARCHAR DESCRIPTION 75057 0 10 4 2017
10000 VARCHAR DESCRIPTION 75057 0 11 5 2017
10000 VARCHAR DESCRIPTION 75057 0 12 6 2017
10000 VARCHAR DESCRIPTION 75057 0 13 7 2017
Run Code Online (Sandbox Code Playgroud)
我需要的是NEEDED_CALC在上个月的bin_flag更改时重置calc 的列.
因此,如果bin_flag = 1和前一个月bin_flag(通过lag函数确定)不同,那么计数器列NEEDED_CALC将重置并再次开始1.
这是一个"差距和岛屿"问题.关键是将组标识符分配给具有相同值的相邻行.有两种简单的方法可以做到这一点:一种是基于,lag()另一种是row_number()s 的区别.
第二个是更简单,只需要一个子查询级别:
select t.*,
row_number() over (partition by fk_id, bin_flag, seqnum_ym - seqnum_bym
order by year, month
) as needed_calc
from (select t.*,
row_number() over (partition by fk_id order by year, month) as seqnum_ym,
row_number() over (partition by fk_id order by bin_flag, year, month) as seqnum_bym
from mytable t
) t;
Run Code Online (Sandbox Code Playgroud)
行数的差异并不难理解,但确实需要概念上的飞跃.我建议您运行子查询并查看值的用途seqnum_ym并seqnum_bym了解其工作原理.
| 归档时间: |
|
| 查看次数: |
783 次 |
| 最近记录: |