У меня есть такие данные:
MON MONTH_NUM OPEN_AT_BEG OPENED CLOSED
Jan 1 34 19 21
Feb 2 (null) 12 12
Mar 3 (null) 10 8
Apr 4 (null) (null) (null)
May 5 (null) (null) (null)
Jun 6 (null) (null) (null)
Эти данные были созданы с помощью этого кода:
select 'Jan' mon, 1 month_num, 34 open_at_beg, 19 opened, 21 closed from dual
union select 'Feb', 2 month_num, null open_at_beg, 12 opened, 12 closed from dual
union select 'Mar', 3 month_num, null open_at_beg, 10 opened, 8 closed from dual
union select 'Apr', 4 month_num, null open_at_beg, null opened, null closed from dual
union select 'May', 5 month_num, null open_at_beg, null opened, null closed from dual
union select 'Jun', 6 month_num, null open_at_beg, null opened, null closed from dual
order by month_num
Я хочу сделать одну вещь:
- Создать новый столбец
NEW_OPEN_AT_BEG
(NEW_OPEN_AT_BEG
= Предыдущий месяц OPEN_AT_BEG
+ Предыдущий месяц OPENED
- Предыдущий месяц CLOSED
)
Окончательный результат должен выглядеть следующим образом:
MON MONTH_NUM OPEN_AT_BEG OPENED CLOSED NEW_OPEN_AT_BEG
Jan 1 34 19 21 34
Feb 2 (null) 12 12 32
Mar 3 (null) 10 8 32
Apr 4 (null) (null) (null) (null)
May 5 (null) (null) (null) (null)
Jun 6 (null) (null) (null) (null)
Этот результат основан на том, что сегодня апрель, поэтому все заполнено до предыдущего месяца (марта).
Я пробовал это ...
with test as (
select 'Jan' mon, 1 month_num, 34 open_at_beg, 19 opened, 21 closed from dual
union select 'Feb', 2 month_num, null open_at_beg, 12 opened, 12 closed from dual
union select 'Mar', 3 month_num, null open_at_beg, 10 opened, 8 closed from dual
union select 'Apr', 4 month_num, null open_at_beg, null opened, null closed from dual
union select 'May', 5 month_num, null open_at_beg, null opened, null closed from dual
union select 'Jun', 6 month_num, null open_at_beg, null opened, null closed from dual
order by month_num
)
select test.*,
case when month_num = 1 then open_at_beg
else lag(open_at_beg + opened - closed,1,0) over(order by month_num)
end new_open_at_beg
from test
order by month_num
что привело к этому ...
MON MONTH_NUM OPEN_AT_BEG OPENED CLOSED NEW_OPEN_AT_BEG
Jan 1 34 19 21 34
Feb 2 (null) 12 12 32
Mar 3 (null) 10 8 (null)
Apr 4 (null) (null) (null) (null)
May 5 (null) (null) (null) (null)
Jun 6 (null) (null) (null) (null)
Он правильно определил число NEW_OPEN_AT_BEG
для февраля как 32. Однако март равен null
для NEW_OPEN_AT_BEG
, поскольку функция задержки не является рекурсивной.
Как написать рекурсивную функцию запаздывания для сбора данных за предыдущий месяц и использования в расчетах?