2016-09-24 7 views
1

これは可能だと思いますが、膨大な研究と無駄な時間は無駄です。Oracle SQLリセット実行時の合計がゼロの場合

倉庫から商品を販売しています。私はいつ出荷を受け、私は毎日の売上予測(数量)を持っているかを知っています。終了在庫を計算する必要があります。これは、基本的にインベントリ予測の実行合計です。

問題が生じるのは、製品が使い果たされたときに、翌日にはマイナスの在庫がないということです。私が別の貨物を受け取るまで、在庫はゼロになります。予測では、複数回ゼロになる可能性があります(下の例よりはるかに多い)。

SELECT FORECAST_DATE, DAYS_OUT, INBOUND_INVENTORY, FORECAST, 
     ENDING_INVENTORY AS DESIRED_RESULT, 
     SUM(INBOUND_INVENTORY) OVER (PARTITION BY NULL ORDER BY DAYS_OUT) - 
      SUM(FORECAST) OVER (PARTITION BY NULL ORDER BY DAYS_OUT) AS ENDING_INVENTORY 
FROM MRP 

:予測日(startiここ

Visual of the dataset (desired column in yellow)

SQL Fiddle for cracking the case

は私の実際のクエリですNG今日)アウト
日:今日と予測日付の間の日数
インバウンド在庫:私の見込販売数量
:製品は、今日のために(ここで、製品)
予測来ます在庫の終了
:インバウンド在庫 - 予測+昨日の終了在庫が< = 0の場合は、昨日の昨日の終了在庫。

+0

実際の問題のクエリやデータを記載してください。 –

+0

FORECAST_DATE、 DAYS_OUT、 INBOUND_INVENTORY、 予測、DESIRED_RESULT、 SUM(INBOUND_INVENTORY)OVER(NULL ORDER BY DAYS_OUT BY PARTITION)として ENDING_INVENTORY SELECT - ENDING_INVENTORY AS(DAYS_OUT BY NULLのORDER BY PARTITION)OVER SUM(予報) MRP –

+0

http://sqlfiddle.com/#!4/72750/10 –

答えて

1

ここでは、MODEL句(Oracle 10で導入)を使用したソリューションがあります。

私はforecast_dateの列を含まない - days_outで十分です。

with 
    inputs (days_out, inbound_inventory, forecast) as (
     select 0, 24, 0 from dual union all 
     select 1, 0, 124 from dual union all 
     select 2, 0, 154 from dual union all 
     select 3, 0, 316 from dual union all 
     select 4, 780, 119 from dual union all 
     select 5, 780, 148 from dual union all 
     select 6, 780, 123 from dual union all 
     select 7, 0, 168 from dual union all 
     select 8, 0, 323 from dual union all 
     select 9, 0, 184 from dual union all 
     select 10, 0, 331 from dual union all 
     select 11, 0, 149 from dual union all 
     select 12, 0, 431 from dual union all 
     select 13, 0, 153 from dual union all 
     select 14, 0, 183 from dual union all 
     select 15, 0, 169 from dual union all 
     select 16, 0, 169 from dual union all 
     select 17, 780, 331 from dual 
    ) 
select days_out, inbound_inventory, forecast, ending_inventory 
from inputs 
model 
    dimension by (days_out) 
    measures  (inbound_inventory, forecast, 0 ending_inventory) 
    rules update 
    iterate(1000000) until (previous(ending_inventory[iteration_number + 1]) is null) 
    (
    ending_inventory[iteration_number] = 
      greatest (0, inbound_inventory[cv()] - forecast[cv()] 
          + nvl(ending_inventory[cv() - 1], 0) 
        ) 
) 
; 

出力

DAYS_OUT INBOUND_INVENTORY FORECAST ENDING_INVENTORY 
---------- ----------------- ---------- ---------------- 
     0    24   0    24 
     1     0  124    0 
     2     0  154    0 
     3     0  316    0 
     4    780  119    661 
     5    780  148    1293 
     6    780  123    1950 
     7     0  168    1782 
     8     0  323    1459 
     9     0  184    1275 
     10     0  331    944 
     11     0  149    795 
     12     0  431    364 
     13     0  153    211 
     14     0  183    28 
     15     0  169    0 
     16     0  169    0 
     17    780  331    449 

18 rows selected. 
+0

これは動作します!絶対に素晴らしい。私は本当にあなたの助けに感謝します。 –

1

これは間違いないでしょうか?再帰的な共通テーブル式と呼ばれるものです。

WITH 
cte_mrp as 
(
    Select row_number() over (partition by null order by forecast_date) as line, mrp.* 
    From mrp 
), 
RCTE (line, forecast_date, days_out, inbound_inventory, forecast, /*iteration, anchor,*/ ending_inventory) as 
(
    Select line, forecast_date, days_out, inbound_inventory, forecast, /*0 iteration, 'anchor' anchor,*/ 
     CASE WHEN inbound_inventory-forecast < 0 THEN 0 ELSE inbound_inventory-forecast END ending_inventory 
    From cte_mrp 
    Where line = 1 

    union all 

    Select m.line, m.forecast_date, m.days_out, m.inbound_inventory, m.forecast, /*r.iteration + 1, 'rcte' anchor,*/ 
     CASE WHEN r.ending_inventory+m.inbound_inventory - m.forecast < 0 THEN 0 ELSE r.ending_inventory+m.inbound_inventory - m.forecast END ending_inventory 
    From cte_mrp m 
    Inner join rcte r on (r.line = (m.line-1)) 
) 

Select * From RCTE; 
+0

それだけでなく、実際には可能です!私はちょうどテストし、それは完璧です。注意: 'row_number()'では、 "by by by by"句は必須ではありません。単純に入れないでください。 (一方で、実際にOPが何かで分割する必要がある場合は、そうしたように書くことで、その変更を簡単に行うことができます)。 – mathguy

+0

@mathguyありがとうございました。ええ、私は知っています。私はちょっと物語を明示するのが好きです。あなたのコメントは、しかし、OPに便利かもしれません。 Btw、あなたのMODELソリューションはあまりにも綺麗すぎるようです。私はMODEL句全体のコンセプトをまだ理解していないので、実際には分かりません。 – Demo

+0

私はちょうどMODEL節を昨日どのように使用するかを学びました(OTNの問題に取り組んでいます)。時間と関心があればそれほど複雑ではありません。私はITプロフェッショナル(または学生)でもないので、それほど難しくありません。 :-) – mathguy

関連する問題