7

これは、私のプロジェクトに役立つ興味深い記事です。

セットベースのスピード詐欺師: FIFO ストック インベントリ SQL 問題:

仮想の在庫倉庫に出入りする在庫の動きを追跡するために使用する在庫テーブル。当社の倉庫は最初は空で、在庫購入 (tranCode = 'IN') の結果として、またはその後の返品 (tranCode = 'RET') により在庫が倉庫に移動し、次の場合に在庫が倉庫から移動します。販売されています (tranCode = 'OUT')。在庫項目の各タイプは、ArticleID によって識別されます。特定のアイテムの購入、販売、または返品により、在庫が倉庫に出入りするたびに、行が Stock テーブルに追加され、StockID ID 列の値によって一意に識別され、その数が記述されます。アイテムの追加または削除、購入価格、取引日など。

私は進行中のプロジェクトでこれを使用していますが、すべてのトランザクションで料金を請求する方法に固執しています。顧客に請求する金額を決定するには、この値が必要です。

  1. まず、5 個のリンゴ (各 $10.00) をストックに追加します。合計 $50.00 になります。

  2. リンゴ3個(各$20.00)を合計8個のリンゴに追加すると、合計価格は$110.00になります

  3. 次に、6 つのアイテムを取り出します (各 10.00 ドルと 20.00 ドルごとに 1 つ) 合計 70 ドル

  4. 取引後、リンゴ 2 個 @$20 が残り、合計 $40 になります。


 Here's my current table
 Item    transaction code    qty     price   
 apple   IN                    5     10.00    
 apple   IN                    3     20.00   
 apple   OUT                   6          

 Manual computation for the OUT transaction price (FIFO)
 QTY     price   total price 
 5       10.00   50.00 
 1       20.00   20.00 
 TOTAL:6         70.00 

 Output of the script:
 Item    CurrentItems   CurrentValue
 apple   2            40.00

 What I need:
 Item    transaction code    qty     price   CurrentItems    CurrentValue 
 apple   IN                    5     10.00   5               50.00 
 apple   IN                    3     20.00   8               110.00 
 apple   OUT                   6             2                   40.00 

 This too will be OK
 Item    transaction code    qty     price   CurrentItems    
 apple   IN                    5     10.00   0               
 apple   IN                    3     20.00   0                
 apple   OUT                   6         70 

コンテストで優勝した投稿されたスクリプトは非常に役に立ちました。「OUT」トランザクションごとの価格を取得する方法について、誰かが私を助けてくれることを願っています

4

5 に答える 5

2

次のようにテーブルを設計することをお勧めします。テーブルに新しいフィールド、つまりqty_outを追加します。

販売前の表:

Item transaction code    qty     qty_out  price   
 apple   IN                    5    0        10.00    
 apple   IN                    3    0        20.00   
 apple   OUT                   6    null

そして、6つのアイテムを販売した後のテーブル:

Item    transaction code    qty     qty_out  price   
 apple   IN                    5    5        10.00    
 apple   IN                    3    1        20.00   
 apple   OUT                   6    null

「qty」と「qty_out」(INトランザクションの場合)を比較して、価格を確認できます。

于 2013-02-19T20:28:15.560 に答える
0

記事に基づいて、スクリプトが得た結果は在庫の値でした。すべての在庫を計算する代わりに、最初の N 個のアイテムのみを使用するように、これを変更する必要があります。

在庫アイテムと取り出したい数を知っているので、現在の合計と照合して、各「IN」からアイテムの数を設定する CASE ステートメントをお勧めします。

于 2012-12-04T05:22:16.863 に答える
0

以下の TSQL のコードを参照してください。基本的な考え方は

  1. 販売行ごとに、数量が Qty であるとします。現在の行より前の累計売上高を計算し、Previous_Sold と呼びます。

  2. ステップ 1 の売り行ごとに、すべての PREVIOUS 買い行を見つけて、その買いまでの現在の合計在庫を計算し、Previous_Running_Stock と呼びます。

  3. ステップ 2 で行を購入する場合は、計算します

Open_Stock = Previous_Running_Stock - Previous_Sold

Close_stock = Previous_Running_Stock - Previous_Sold - 数量

  1. 次の場合に購入行をフィルタリングして保持する

open_stock >0、売り注文を約定するのに十分な在庫があることを意味します

close_stock < 0: 購入行の在庫がすべて使い尽くされたことを意味します。または、close_stock >= 0 で最も早い (最初の行)、その行からの購入が部分的に使用されたことを意味します。

  1. ステップ 4 で LIFO コストを取得するための価格と数量の集計 (合計積)。

LIFOや平均原価にも簡単に変更できると思います。

--initial table of trades
item       item_trade_order     direction  unit_price    qty
Apple      1                    buy        10            100
Apple      2                    buy        9             150
Blueberry  1                    buy        5             300   
Apple      3                    sell       12            50
Apple      4                    buy        11            200
Apple      5                    sell       10            350
Blueberry  2                    sell       10            50


--code, using CTE


; with step1 as
(
    select *
        , coalesce(sum(case direction when 'sell' then 1 else 0 end * qty) over(partition by item order by item_order rows between unbounded preceding and 1 preceding), 0) Previous_Sold
    from trade 
)
, step2_3 as
(
    select *
        , Previous_running_stock - Previous_Sold Open_Stock
        , Previous_running_stock - Previous_Sold - qty Close_Stock
        , ROW_NUMBER() over(partition by item, item_order order by (case when Previous_running_stock - Previous_Sold - qty < 0  then null else 0 - item_order end) desc) rnk
    from step1 t1
    cross apply
    (
        select item_order batch_order, price batch_prc, qty batch_qty
            , sum(qty) over(order by item_order rows unbounded preceding) Previous_running_stock
        from trade
        where direction = 'buy'
        and item = t1.item
        and item_order < t1.item_order
    ) batch
    where t1.direction = 'sell'
)
, step4 as
(
    select *
    from step2_3
    where Open_Stock > 0
    and (Close_Stock < 0 or rnk = 1)
)
select item, item_order, direction, AVG(price) prc, AVG(qty) qty
    ,   sum(case when Close_Stock > 0 then batch_qty - close_stock else case when open_stock < batch_qty then open_stock else batch_qty end end * Batch_Prc) / nullif(avg(qty), 0) FifoUnitCost
from step4
group by item, item_order, direction
order by item, item_order
于 2016-04-27T16:03:48.013 に答える
0

各 OUT トランザクション自体を追跡することはできませんが、最後の (計算するものを除く) IN または OUT 行と、現在の値の列と、計算したい現在の値を引いた値を取得することで計算できます。

この例では

StockID  ArticleID  TranDate  TranCode  Items    Price    CurrentItems  CurrentValue
4567     10000      10:45:07  IN          738   245.94             738    181,503.72
21628    10000      12:05:25  OUT         600                      138     33,939.72
22571    10000      14:39:27  IN           62   199.95             200     46,336.62
30263    10000      16:14:13  OUT         165                       35      6,998.25
42090    10000      18:18:58  RET           5                       40      7,998.00
53143    10000      20:18:54  IN          500   135.91             540     75,953.00

トランザクション 30263 の場合、価格は 46,336.62 - 6,998.25 = 39,338.37になります。

于 2014-08-26T08:43:13.427 に答える
0

商品アイテムごとに行を持つテーブルを作成して、各リンゴの行が価格と在庫状況 (売れ残り/売れ残り) と共に挿入されるようにするにはどうすればよいでしょうか。
次に、必要な各製品に関連付けられた価格で、上位 n 個のアイテムを選択するだけです。基本的に、アイテムのキューを作成し、キューの先頭 (挿入日が最も古い) から「売れ残った」アイテムを削除するだけです。

于 2012-06-26T21:08:22.173 に答える