【问题标题】:Calculating Value pro rata over months with Oracle使用 Oracle 按比例计算数月的价值
【发布时间】:2014-12-22 15:21:03
【问题描述】:

假设我有一个包含我的用户订阅期限的表格,例如:

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

【问题讨论】:

  • T00Z/2 月的值 0.9 如何计算?
  • T00Z 的期限为 23 天,1 月份为 21 天,2 月份为 2 天,因此它的价值分为 1 月份花费的 ~95% ($19.1) 和 ~5% ($0.9) 2 月花费。

标签: oracle oracle11g window-functions


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 2020-08-06
    • 1970-01-01
    相关资源
    最近更新 更多