1

次のデータがあります。

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

つまり、欠落している日付を作成し、製品コードを複製して金額を計算します。

4

2 に答える 2

5

LEAD関数と階層クエリを組み合わせて使用​​すると、これを 1 つのクエリで実現できます。

ここでデモ。

    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
于 2013-07-13T05:29:57.580 に答える
2

product_mounts がこのテーブルの名前だと思います。

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;
于 2013-07-12T21:51:53.143 に答える