很久之前就想寫出來,就是因爲自己太懶,憋了怎麼久。本文關於使用ORACLE分析函數對一些經濟指標進行計算。表indi_value有3個關鍵的字段:indi_date,indi_value,indi_id分別對應 指標日期,指標值,指標ID。這個表中保存了很多種類的經濟指標,如CPI,RPI,GDP,這些指標通過 指標ID來標識。下面是針對CPI做的處理,公式如下:
公式說明:將2010年1月份當作基期。分別計算基期前後的定基價格指數。直接看代碼
with base as ( select indi_date,indi_value
from indi_value
-- 獲取20060101 - 20131101區間內要計算的數據
where indi_id='C0A0102' and indi_date between '20060101' and '20131101'
),
---獲取大於基期的數據,數據按日期升序,並且使基期=100,往後的值都爲空,然後通過行間計算,進行填補
up as (select indi_date,indi_value,
case when indi_date like '201001%'
then 100 else null end as v,rank() OVER(order by indi_date) as d
from base
where indi_date between '20100101' and '20131101'),
upx as (select d,v
from up model
dimension by (d)
measures (indi_value,v)
RULES UPDATE
(
V[d>1]=v[cv(d)-1]*(1+(indi_value[cv(d)]-100)/100) --大於基期的計算公式
)
),
--獲取小於基期的數據,結尾日期要能夠將基期數據包含到要計算的數據中,數據按日期倒序,
--並且使基期=100,往後的值都爲空,然後通過行間計算,進行填補
down as (select indi_date,indi_value,
case when indi_date like '201001%'
then 100 else null end as v,rank() OVER(order by indi_date desc) as d
from base
where indi_date between '20060101' and '20100201'),
downx as (select d,v
from down model
dimension by (d)
measures (indi_value,v)
RULES UPDATE
(
V[d>1]=v[cv(d)-1]/(1+(indi_value[cv(d)-1]-100)/100) --小於基期的計算公式
)
)
select u.indi_date,null as v,null as r,x.v as b
from upx x join up u on x.d=u.d
union
select d.indi_date,null as v,null as r, x.v as b
from downx x join down d on x.d=d.d
第一部分:主要是獲取要計算的時間區間內的所有數據,並放到一個名叫base的臨時表中。
with base as ( select indi_date,indi_value
from indi_value
-- 獲取20060101 - 20131101區間內要計算的數據
where indi_id='C0A0102' and indi_date between '20060101' and '20131101'
),
第二部分:計算大於基期的那部分數據
---獲取大於基期的數據,數據按日期升序,並且使基期=100,往後的值都爲空,然後通過行間計算,進行填補
up as (select indi_date,indi_value,
case when indi_date like '201001%'
then 100 else null end as v,rank() OVER(order by indi_date) as d
from base
where indi_date between '20100101' and '20131101'),
upx as (select d,v
from up model
dimension by (d)
measures (indi_value,v)
RULES UPDATE
(
V[d>1]=v[cv(d)-1]*(1+(indi_value[cv(d)]-100)/100) --大於基期的計算公式
)
)
第三部分:計算小於基期的那部分數據,原理同第二部分。但要注意是數據日期的倒序。
第四部分:將第二,第三部分的計算結果整合起來
select u.indi_date,null as v,null as r,x.v as b
from upx x join up u on x.d=u.d
union
select d.indi_date,null as v,null as r, x.v as b
from downx x join down d on x.d=d.d
其中第二,第三部分又可以分爲2個步驟。
(1)是還是獲取要計算的數據,並添加一列作爲計算結果,且基期對應的值爲100。添加一列排序號作爲(2)步的取值下標。
(2)使用oracle提供的行間計算函數 model 來根據(1)中的indi_value,和 第一行的基期結果100來計算第二行的定基價格指數。
這樣就會一行一行的計算下去,後一行的結果總是基於前一行的值來計算。(1)中的列 d 可以起類似於數組的作用。
measures 後面的 rules update是可以去掉的。