假设我有一个包含用户订阅条款的表,例如:
user product value start_date end_date
Scott T23K 250 15/01/2014 15/02/2015
Tiger T23K 200 05/01/2014 05/02/2015
Scott T00Z 20 10/01/2014 02/02/2015
...
我想根据我的结算周期(每月)制作收入报告,如下所示:
month product value
Jan/2014 T23K 275
Jan/2014 T00Z 19.1
Feb/2014 T23K 275
Feb/2014 T00Z 0.9
我想我可以查询like this,不过我想知道是否有一个聪明的分析函数或某些东西可以使它看起来更好。想法?
我正在使用Oracle 11gR2
答案 0 :(得分:1)
试试这个,我觉得它符合你的情况:
with subscriptions as
(
select 'Scott' user_, 'T23K' product , '250' value , to_date('15/01/2014','DD/MM/YYYY') start_date , to_date('15/02/2015','DD/MM/YYYY') end_date from dual
union all
select 'Tiger' user_, 'T23K' product , '200' value , to_date('05/01/2014','DD/MM/YYYY') start_date , to_date('05/02/2015','DD/MM/YYYY') end_date from dual
union all
select 'Scott' user_, 'T00Z' product , '20' value , to_date('10/01/2014','DD/MM/YYYY') start_date , to_date('02/02/2014','DD/MM/YYYY') end_date from dual
)
, allMonts as
(select add_months(to_date('01/01/2010','DD/MM/YYYY'),rownum) myMonth , lag(add_months(to_date('01/01/2010','DD/MM/YYYY'),rownum)) over (order by rownum desc) -add_months(to_date('01/01/2010','DD/MM/YYYY'),rownum) daymonth from dual CONNECT BY LEVEL <= 100
)
, detail as
(
select s.*,allMonts.myMonth, end_date-start_date duration,
case when trunc(start_date,'MON')=trunc(end_date,'MON') then (end_date-start_date)*value/( end_date-start_date)
when trunc(start_date,'MON')=allMonts.myMonth then (add_months(allMonts.myMonth,1) - start_date)*value/( end_date-start_date)
when trunc(end_date,'MON')=allMonts.myMonth then (end_date - allMonts.myMonth )*value/( end_date-start_date)
else allMonts.daymonth*value/( end_date-start_date)
end value_by_month
from subscriptions s , allMonts
where allMonts.myMonth
between trunc(s.start_date,'MON') and trunc(s.end_date,'MON')+1
)
select myMonth, product, sum(value_by_month)
from detail
group by rollup(myMonth), product