簡體   English   中英

Oracle 遞歸滯后函數

[英]Oracle Recursive Lag Function

我有這樣的數據:

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。但是,三月對於NEW_OPEN_AT_BEGnull ,因為滯后函數不是遞歸的。

如何編寫遞歸滯后函數來獲取上個月的數據並用於計算?

我想你想要累計金額:

select t.*,
       (case when open_at_beg is not null then open_at_beg
             when closed is not null and opened is not null
             then (sum(open_at_beg) over () +
                   sum(opened - closed) over (order by month_num rows between unbounded preceding and 1 preceding)
                  )
        end) as new_open_at_beg
from test t;

是一個 db<>fiddle。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM