首页 > 解决方案 > SQL-基于条件的累积和

问题描述

我有一个场景,我必须根据以下数据计算计数器。如果状态为 A、B、C,则计数器应为 0,这工作正常。

如果 STATUS 是 D 计数器应该做一个累积和,但如果状态在两者之间发生变化(如在 201907 中),计数器应该再次重置并且 sum 应该从 1、2、3 重新开始,依此类推。任何可能的帮助都会受到赞赏。

输入 - 3 列 - Customer_No、日期、状态

CUSTOMER_NO Date        STATUS  
1234        201901          A   
1234        201902          B   
1234        201903          C   
1234        201904          D   
1234        201905          D   
1234        201906          D   
1234        201907          C   
1234        201908          D   
1234        201910          D   
1234        201911          D   
1234        201912          D

预期输出 - 输入列 + 计数器列

CUSTOMER_NO     Date     STATUS  COUNTER
----------------------------------------
1234            201901      A       0
1234            201902      B       0
1234            201903      C       0
1234            201904      D       1
1234            201905      D       2
1234            201906      D       3
1234            201907      C       0
1234            201908      D       1
1234            201910      D       2
1234            201911      D       3
1234            201912      D       4

样本数据

谢谢

标签: sqlsql-server

解决方案


这是差距和孤岛问题的变体。对于这个特定的化身,您可以通过计算给定行之前的非 D 状态的数量来识别岛屿。

确定组后,使用caseand row_number()

select t.*,
       (case when status = 'D'
             then row_number() over (partition by customer_no, grp, status order by date)
             else 0
        end) as counter
from (select t.*,
             sum(case when status <> 'D' then 1 else 0 end) over (partition by customer_no order by date) as grp
      from t
     ) t

推荐阅读