這可以通過普通的SQL簡單而高效地完成 - 不需要過程代碼。
我不確定你想要什麼輸出格式,但你應該能夠適應你的需求。
從你所描述的,你正在尋找LAST_VALUE()
功能,而不是LAG()
。 LAST_VALUE()
允許您忽略空值。注意窗口子句(ROWS BETWEEN...
) - 默認是包含當前行,而您不需要這樣做,所以您必須有明確的窗口子句。
編輯:作爲@boneist在下面評論指出,自從甲骨文11.2 LAG()
添加IGNORE NULLS
選項的功能 - 它的優點是,默認情況下它會尋找「背」在早先的行,開始了最近 - 所以窗口條款將不再需要。在Oracle 11.2或更高版本中,而不是下面顯示的LAST_VALUE()
函數,可以使用LAG(prc_b ignore nulls) over (order by dt)
。
with
test_data (dt, prc_a, prc_b) as (
select date '2017-05-01', 10, 10 from dual union all
select date '2017-06-01', null, 10 from dual union all
select date '2017-07-01', 10, null from dual union all
select date '2017-08-01', 10, null from dual union all
select date '2017-09-01', null, 20 from dual
)
-- End of test data (not part of the solution). SQL query begins below this line.
select dt, prc_a, prc_b,
case when prc_a is null
then prc_b - last_value(prc_b ignore nulls) over (order by dt
rows between unbounded preceding and 1 preceding)
end as prc_b_diff
from test_data
;
DT PRC_A PRC_B PRC_B_DIFF
---------- ---------- ---------- ----------
2017-05-01 10 10
2017-06-01 10 0
2017-07-01 10
2017-08-01 10
2017-09-01 20 10
很好解釋!謝謝你給我介紹這個函數 – ana
@mathguy從11g開始,[LAG](https://docs.oracle.com/cloud/latest/db112/SQLRF/functions082.htm#SQLRF00652)/ LEAD也有忽略空功能,所以你可以簡化你的解決方案。 – Boneist
@骨科醫生 - 好點!我從去年開始就一直在學習Oracle,所以我應該知道這一點 - 我只從11.2和12.1的文檔中讀到;因爲我從來不需要這個,所以我從來沒有學過。我將編輯帖子以添加此替代方案。 – mathguy