Oracle SQL - 根据月份对时间序列分区求和

Oracle SQL - Summing a time series partition based on month

我正在处理如下所示的数据集:

MTD       | ID | Active
-----------------------
01-APR-16 | A  | y
01-MAY-16 | A  | y
01-JUN-16 | A  | n
01-JUL-16 | A  | y
01-AUG-16 | A  | n
01-APR-16 | B  | n
01-MAY-16 | B  | y
01-JUN-16 | B  | y
01-JUL-16 | B  | y
01-AUG-16 | B  | y

我想向数据集添加一个计数列,用于计算在当前 MTD 之后 ID 处于活动状态 ('y') 的次数。期望的输出是:

MTD       | ID | Active | COUNT
-------------------------------
01-APR-16 | A  | y      | 2
01-MAY-16 | A  | y      | 1
01-JUN-16 | A  | n      | 1
01-JUL-16 | A  | y      | 0
01-AUG-16 | A  | n      | 0
01-APR-16 | B  | n      | 4
01-MAY-16 | B  | y      | 3
01-JUN-16 | B  | y      | 2
01-JUL-16 | B  | y      | 1
01-AUG-16 | B  | y      | 0

我想到的查询是:

SELECT 
 MTD,

 ID, 

 ACTIVE,

 SUM(CASE WHEN MTD > (current records MTD) 
          AND ACTIVE = 'y' THEN 1 ELSE 0 END) 
          OVER (PARTITION BY ID) 
   as COUNT

我不确定如何在 window 总和中比较每条记录的 MTD 与当前记录的 MTD。如何修改case语句的第一行?

谢谢,

瑞安·巴克

对我来说,您似乎想用 "y" 反向求和行数。像这样:

select t.*,
       greatest(sum(case when active = 'y' then 1 else 0 end) over (partition by id order by mtd desc) - 1,
                0)
from t;

你的想法很接近。您只需要在分区子句中使用 order by

count() over()range 规范一起使用,这样您就可以查看当前行之后的行(对于每个 id)是否有活动标志 y 并且只对它们进行计数。这假设 mtd 是用于排序的 date 列。

SELECT 
 MTD,
 ID, 
 ACTIVE,
 COUNT(case when active='y' then 1 end) OVER(partition by ID order by mtd range between 1 following and unbounded following)
FROM your_table

Sample Demo