02_窗口函数:实例学习 - 巧用ROW_NUMBER() 查询连续出现某值的最大次数


一、任务描述

如图,要查询同一个客户(USER_ID)同一账户(ACCT_ID)下,近12个月(MONTH_NBR)连续出现同一个状态(FLAG:0 或 1)的最大次数。

二、任务测试过程

1. 创建测试表结构

--DROP TABLE TEST_FOR_ROW;
CREATE TABLE TEST_FOR_ROW
(
USER_ID VARCHAR(100)
,ACCT_ID VARCHAR(100)
,MONTH_NBR NUMBER(10)
,FLAG NUMBER (10)
);

2. 创建批量插入数据的存储过程

CREATE OR REPLACE PROCEDURE PROC_TABLE_FOR_TEST_ROW AS 

NM_1 NUMBER := 1;
NM_2 NUMBER := 1;
NM_3 NUMBER := 1;

BEGIN
  NM_1 := 1;
  WHILE NM_1 <= 12 LOOP
    NM_2 := 1;
    WHILE NM_2 <= 3 LOOP
      NM_3 := 1;
      WHILE NM_3 <= 3 LOOP
        INSERT INTO TEST_FOR_ROW (USER_ID, ACCT_ID, MONTH_NBR, FLAG) VALUES('C1'||NM_3, 'A1'||NM_2, NM_1, CAST(DBMS_RANDOM.VALUE(0, 1) AS INT));
        COMMIT;
        NM_3 := NM_3 + 1;
      END LOOP;
      NM_2 := NM_2 + 1;
    END LOOP;
    NM_1 := NM_1 + 1;
  END LOOP;
  
END PROC_TABLE_FOR_TEST_ROW;

3. 执行存储过程插入数据

BEGIN
  PROC_TABLE_FOR_TEST_ROW;
END;

4. 执行查询语句

--step3
SELECT
  USER_ID AS USER_ID
  ,ACCT_ID AS ACCT_ID
  ,FLAG AS FLAG
  ,MAX(CONTINUE_CNT) AS MAX_CONTINUE_CNT
FROM
(
  --step2
  SELECT 
    USER_ID AS USER_ID
    ,ACCT_ID AS ACCT_ID
    ,FLAG AS FLAG
    ,NM AS NM
    ,COUNT(*) AS CONTINUE_CNT
  FROM
  (
    --step1
    SELECT
      USER_ID AS USER_ID
      ,ACCT_ID AS ACCT_ID
      ,MONTH_NBR AS MONTH_NBR
      ,FLAG AS FLAG
      ,ROW_NUMBER() OVER(PARTITION BY USER_ID, ACCT_ID ORDER BY MONTH_NBR) AS NM_1
      ,ROW_NUMBER() OVER(PARTITION BY USER_ID, ACCT_ID, FLAG ORDER BY FLAG) AS NM_2
      ,ROW_NUMBER() OVER(PARTITION BY USER_ID, ACCT_ID ORDER BY MONTH_NBR) 
      - ROW_NUMBER() OVER(PARTITION BY USER_ID, ACCT_ID, FLAG ORDER BY MONTH_NBR) AS NM
    FROM
      TEST_FOR_ROW
  )
  GROUP BY
    USER_ID
    ,ACCT_ID
    ,FLAG
    ,NM
  ORDER BY 
     USER_ID
    ,ACCT_ID
    ,NM
)
GROUP BY
  USER_ID
  ,ACCT_ID
  ,FLAG
ORDER BY 
   USER_ID
  ,ACCT_ID
  ,FLAG
;

按照以上查询语句里的step1、step2、step3进行分步执行,如下图:

step1:

step2:

step3:


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM