2016-09-24 67 views
1

我想這是可能的,但廣泛的研究和無數小時還沒有收到回報。Oracle SQL Reset零時運行總數

我正在銷售倉庫產品。我知道什麼時候我會收到貨物,並且每天都有銷售預測(數量)。我需要計算結束庫存。它基本上是庫存 - 預測的運行總和。

問題是,當我用完產品時,第二天我不會有負面的庫存,因爲運行總和會提示。在我收到另一批貨物之前,庫存將爲零。它可以在預測中多次下降到零(遠遠超過下面的例子)。

Visual of the dataset (desired column in yellow)

SQL Fiddle for cracking the case

這裏是我的實際查詢:

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 NG今天)
天出:今天和預測日期之間的天數
入境庫存:產品未來在(今天,這裏的產品)
預測:我預計銷售數量
結束庫存:入庫庫存 - 預測+如果昨天的結束庫存< = 0,則返回0,否則爲昨天的結束庫存。

+0

請在實際問題的查詢和數據。 –

+0

SELECT FORECAST_DATE, DAYS_OUT, INBOUND_INVENTORY, 預測, ENDING_INVENTORY如DESIRED_RESULT, SUM(INBOUND_INVENTORY)OVER(PARTITION BY NULL ORDER BY DAYS_OUT) - SUM(預測)OVER(PARTITION BY NULL ORDER BY DAYS_OUT)AS ENDING_INVENTORY FROM 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()'中,「partition by」子句不是強制性的,你可能根本就不把它放在裏面。 (另一方面,如果實際上OP需要按某種方式進行劃分,那麼像你這樣寫就會使更容易做出改變。)幹得好! – mathguy

+0

@mathguy謝謝。是的,我知道。我只是想明確一些東西。儘管您的評論可能對OP有用。順便說一句,你的MODEL解決方案看起來很整潔,但我仍然無法掌握整個MODEL子句的概念,所以我無法真正瞭解。 – Demo

+0

我剛剛學會了如何使用MODEL子句(在OTN上解決問題) - 如果您有時間和興趣,它並不那麼複雜。我甚至不是IT專業人員(或學生),所以它不是太難。 :-) – mathguy