具有条件的先前行的总和

时间:2017-02-28 20:59:55

标签: sql oracle

我试图总结一列,在有序列上提供了一些有点非直接的条件。

请参阅以下示例了解我要做的事情:

这就是我现在所拥有的......

--------------------------------------------------
 ID | Month | Days -----------> ID | Month | Days_Cumulative     
--------------------------------------------------
 AB | 2012/01 | 22 -----------> AB | 2012/01 | 22
--------------------------------------------------
 AB | 2012/02 | 23 -----------> AB | 2012/02 | 45
--------------------------------------------------
 AB | 2012/03 | 28 -----------> AB | 2012/03 | 73
--------------------------------------------------
 AB | 2013/07 | 11 -----------> AB | 2013/07 | 11
--------------------------------------------------
 AB | 2013/08 | 15 -----------> AB | 2013/08 | 99
--------------------------------------------------

这就是我希望实现的目标..

--------------------------------------------------
 ID | Month | Days -----------> ID | Month | Days_Cumulative     
--------------------------------------------------
 AB | 2012/01 | 22 -----------> AB | 2012/01 | 22
--------------------------------------------------
 AB | 2012/02 | 23 -----------> AB | 2012/02 | 45
--------------------------------------------------
 AB | 2012/03 | 28 -----------> AB | 2012/03 | 73
--------------------------------------------------
 AB | 2013/07 | 11 -----------> AB | 2013/07 | 11
--------------------------------------------------
 AB | 2013/08 | 15 -----------> AB | 2013/08 | 26
--------------------------------------------------

我在第一个表中'Days_Cumulative'列的最后一行是99,它应该是26,因为我试图仅连续几个月的天数总和(我的逻辑当前总结了特定ID的所有行)。现在,我知道为什么我的查询给了我结果,然而,我不知道的是如何得到我正在寻找的东西。基本上,我想要

 Sum(T1.DAYS) over(partition by T1.ID order by T1.Month)

一旦新的连续月线开始,重新开始这笔钱。我的查询可能有点乱 - 只要我加入我的源表两次 - 但我一次只是在这一步中工作,无法在任何地方为我的特定问题找到解决方案。

这是我的问题:

WITH SRC AS
(Select ID, Month, Days 
, ROW_NUMBER() over(partition by ID order by Month) RN
from TABLE)
Select T1.ID, T1.Month, T1.Days
, CASE WHEN MONTHS_BETWEEN(T1.Month, T2.Month) > 1 THEN T1.DAYS
ELSE Sum(T1.DAYS) over(partition by T1.ID order by T1.Month) END AS Days_Cumulative
from SRC T1
Left Join SRC T2
On T1.ID = T2.ID
and T1.RN = T2.RN - 1 
Left Join SRC T3
On T1.ID = T3.ID
and T1.RN = T3.RN + 1 

任何见解都会有所帮助。

2 个答案:

答案 0 :(得分:1)

您需要定义连续月份的时段。有几种方法可以做到这一点。我会使用row_number()

来改变一下
select id, month, days,
       sum(days) over (partition by id, grp order by month) as running_days
from (select . . .,
             add_months(month, -row_number() over (partition by id order by month)) as grp
      from . . .  -- not really sure what goes here
     ) t;

请注意,您的查询和示例数据完全不同。以上显示了应该采取的结构。你必须根据你的实际表格进行调整。

答案 1 :(得分:0)

您可以根据连续性创建群组,然后在群组中找到累积总和:

with cte
as (
    select ID,
        Month,
        Days,
        case 
            when to_date(month, 'yyyy/mm') 
            = lag(add_months(to_date(month, 'yyyy/mm'), 1)) 
                    over (order by Month) 
            then 0 else 1 end x
    from table
    )
select
    t.*,
    sum(Days) over (partition by grp order by month)
from (
    select
        t.*,
        sum(x) over (order by Month) grp
    from src t
) t;