Я пытаюсь суммировать по столбцу при условии несколько непростое условие для упорядоченного столбца.

Пожалуйста, посмотрите следующий пример для того, что я пытаюсь сделать:

Это то, что у меня сейчас есть ..

--------------------------------------------------
 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, поскольку я пытаюсь суммировать дни только для непрерывных месяцев (моя логика в настоящее время суммирует все строки для определенного идентификатора). Теперь я знаю, почему мой запрос дает мне результаты, однако я не знаю, как получить то, что я ищу. В принципе, я хочу

 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 

Любое понимание будет полезно.

-1
jon 28 Фев 2017 в 23:59

2 ответа

Лучший ответ

Вам необходимо определить периоды непрерывных месяцев. Есть несколько способов сделать это. Я бы пошел на разницу, используя 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
Gordon Linoff 28 Фев 2017 в 21:07

Вы можете создать группу на основе непрерывности, а затем найти совокупную сумму внутри групп:

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;
0
Gurwinder Singh 28 Фев 2017 в 21:50