2013-07-12 30 views
2

我有以下数据:填充在Oracle SQL缺少的行

date   product amount 
2013-01-31 a1   100 
2013-02-28 a1   200 
2013-01-31 b1   700 
2013-04-30 b1   100 
2013-06-30 b1   1300 
2013-03-31 c1   10 
2013-07-31 c1   70 

是否有可能建立在SQL/PLSQL查询,将填充基于日期缺少的行?我的意思是我想得到如下结果:

date   product amount 
2013-01-31 a1   100 
2013-02-28 a1   200 
2013-01-31 b1   700 
*2013-02-28 b1   500* 
*2013-03-31 b1   300* 
2013-04-30 b1   100 
*2013-05-31 b1   700* 
2013-06-30 b1   1300 
2013-03-31 c1   10 
*2013-04-30 c1   25* 
*2013-05-31 c1   40* 
*2013-06-30 c1   55* 
2013-07-31 c1   70 

即创建缺失的日期,重复的产品代码和计算金额。

+1

我不明白,比如为什么** 2013年2月28日B1 ** 500 **或B1 2013年3月31日300 **? –

+0

抱歉,我忘了解释,当我们在产品b1中存在差距时,我们有两个值:一月份为700,四月份为100,当我们填充缺失的行时,差异必须在新日期之间平均分配(700-200 = 300,300-200 = 100)。在4月份我们有100,在1300年6月,所以在失踪的五月份我们应该有700(100 + 600 = 700,700 + 600 = 1300) –

+0

我想你应该先解释一下系统每月的单位产量是多少?产品销售?,是什么使数量在几个月之间发生变化? 例如B1,​​700在一月份然后是四月份的100,这些700是什么使四月份变成了100,然后在六月份变成了1300? – Adrian

回答

3

我假设product_amounts是此表的名称。

declare 
    n integer; 
    i integer; 
    a integer; 
    d date; 
begin 
    for x in 
    (
    select * 
    from (select product, 
        amount, 
        trunc(date, 'MONTH') mon, 
        lead(trunc(date, 'MONTH')) over(partition by product order by date) next_mon, 
        lead(amount) over(partition by product order by date) next_amount, 
      from product_amounts 
      ) 
    where months_between(next_mon, mon) > 1 
) 
    loop 
    n := months_between(x.next_mon, x.mon); 
    for i in 1 .. n-1 
    loop 
     d := add_months(x.mon, i); 
     a := x.amount + (x.next_amount - x.amount)/n; 

     insert into product_amounts(date, product, amount) 
     values (last_day(d), x.product, a); 
    end loop; 
    end loop; 

    commit; 
end; 
+0

非常感谢,dziękuję –

5

使用LEAD功能和hierarchical查询的组合,这可以在一个单一的查询来实现。

演示here

SELECT DISTINCT 
      ADD_MONTHS (product_date, LEVEL - 1), product, amount + ((LEVEL - 1) * mul_factor) 
     FROM (SELECT product_date, product, amount, next_date, 
        amount_diff/month_diff mul_factor 
       FROM (SELECT product_date, product, amount, 
          LEAD (product_date, 1) OVER (PARTITION BY product ORDER BY product_date) 
           AS next_date, 
          MONTHS_BETWEEN (
           (LEAD (product_date, 1) OVER (PARTITION BY product ORDER BY product_date)), 
           product_date) 
           AS month_diff, 
          LEAD (amount, 1) OVER (PARTITION BY product ORDER BY product_date) 
           AS next_amount, 
          LEAD (amount, 1) OVER (PARTITION BY product ORDER BY product_date) 
          - amount 
           AS amount_diff 
         FROM mytable) 
      WHERE next_date IS NOT NULL) 
CONNECT BY ADD_MONTHS (product_date, LEVEL - 1) <= next_date 
    ORDER BY 2, 1 

这里使用LEAD函数获取下一个日期和下一个金额。使用这个,可以找到月份的差异,均匀分配金额所需的金额和金额的差异。这稍后用于分层查询以获取开始和结束日期之间的所有月份。但是,这给了几个重复的行,我似乎无法消除。因此使用了DISTINCT关键字。

输出:

01/31/2013 a1 100 
02/28/2013 a1 200 
01/31/2013 b1 700 
02/28/2013 b1 500 
03/31/2013 b1 300 
04/30/2013 b1 100 
05/31/2013 b1 700 
06/30/2013 b1 1300 
03/31/2013 c1 10 
04/30/2013 c1 25 
05/31/2013 c1 40 
06/30/2013 c1 55 
07/31/2013 c1 70 
+0

非常感谢您的帮助! –