2012-06-26 24 views
5

Ecco un articolo interessante che ho trovato utile il mio progetto:First-in-first-out (FIFO) inventario che costano

Set-based Speed Phreakery: The FIFO Stock Inventory SQL Problem:

della tabella che usiamo per seguire i movimenti della pista di magazzino dentro e fuori dal nostro magazzino immaginario. Il nostro magazzino è inizialmente vuoto e le scorte si trasferiscono nel magazzino a seguito di un acquisto di azioni (tranCode = 'IN'), oa causa di un successivo ritorno (tranCode = 'RET'), e le scorte escono dal magazzino quando è venduto (tranCode = 'OUT'). Ogni tipo di stock è identificato da un ArticleID. Ogni movimento di magazzino all'interno o all'esterno del magazzino, a causa di un acquisto, vendita o restituzione di un determinato articolo, comporta l'aggiunta di una riga alla tabella Stock, identificata in modo univoco dal valore nella colonna Identità StockID e che descrive quanti gli articoli sono stati aggiunti o rimossi, il prezzo per gli acquisti, la data della transazione e così via.

Anche se sto usando questo nel mio progetto in corso, mi sono bloccato su come ottenere il prezzo da addebitare su ogni transazione "OUT". Ho bisogno di avere questo valore per determinare quanto addebiterò ai miei clienti.

  1. Prima aggiungere 5 mele (ciascuna $ 10.00) per il titolo, per un totale di $ 50,00

  2. Aggiungere 3 mele (ciascuna $ 20.00) per lo stock totale di 8 mele, per un prezzo totale di $ 110.00

  3. quindi estrarre 6 articoli (5 ciascuno $ 10.00 e le 1 ciascuno $ 20.00) $ 70 in totale

  4. Dopo l'operazione si lascerà 2 mele @ $ 20 ciascuno per un totale di $ 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 

Lo script inviato che ha vinto il concorso è stato molto utile, spero che qualcuno mi può aiutare su come ottenere il prezzo per 'OUT' operazione

+0

è necessario dare a ogni transazione (In, Out, ret) un numero univoco in modo da poter conoscere la quantità e il prezzo delle mele. In base a ciò è possibile calcolare quanto totale è stato calcolando (qtà * prezzo) –

+0

C'è una chiave primaria nella tabella azionario. è solo che non volevo mostrarlo per semplicità, sto usando anche ItemID invece della parola apple. Non puoi semplicemente calcolare il prezzo per (qtà * prezzo) da solo, ricorda che ho bisogno di implementare la regola FIFO. – samantha07

risposta

0

ne dite di costruire una tabella che ha una riga per articolo prodotto, quindi viene inserita una riga per ogni mela insieme al prezzo e alla disponibilità (invenduti/venduti).
Quindi è sufficiente selezionare le prime n voci, con il prezzo associato a ciascuno dei prodotti desiderati. In sostanza, stai creando una coda di elementi e rimuovendo quelli che sono "invenduti" dalla parte anteriore (con la data di inserimento più vecchia) della coda.

+0

grazie. questo è esattamente ciò che sta facendo il mio tavolo. forse non ho capito il tuo punto, puoi fornirmi un esempio? – samantha07

0

In base all'articolo, il risultato ottenuto è stato il valore dell'inventario. Dovresti modificare questo in modo che, invece di calcolare per tutto l'inventario, usi solo i primi N elementi.

Suggerirei una dichiarazione CASE per impostare il numero di elementi da ogni "IN" mentre si controlla il totale parziale poiché si conoscono gli articoli dell'inventario e il numero che si desidera estrarre.

1

Suggerisco di progettare il tavolo come di seguito: Aggiungi un nuovo campo al tuo tavolo, ad es.qty_out

La tabella prima di vendere:

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

e il tavolo dopo la vendita dei 6 articoli:

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

È possibile confrontare "qty" con "qty_out" (per le operazioni in) per trovare fuori il prezzo.

0

Non è possibile tracciare ciascuna transazione OUT stessa, ma è possibile calcolarla prendendo l'ultima (eccetto per la quale si calcola) la riga IN o OUT e la colonna del valore corrente e il valore corrente meno per il quale si desidera calcolare.

in questo esempio

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 

per la transazione 30263 prezzo sarà 46,336.62 - 6,998.25 = 39,338.37

0

vedere il codice di seguito in TSQL. L'idea di base è

  1. per ogni vendere fila, dire la quantità è Qty, calcolare in esecuzione vendite totali PRIMA alla riga corrente, lo chiamano Previous_Sold.

  2. per ogni riga di vendita nel passaggio 1, trovare tutte le righe di acquisto PRECEDENTI e calcolare le scorte totali in esecuzione FINO A quell'acquisto, chiamarlo Previous_Running_Stock.

  3. per buy righe in fase 2, calcolare

Open_Stock = Previous_Running_Stock - Previous_Sold

Close_stock = Previous_Running_Stock - Previous_Sold - Quantità.

  1. Filtro e solo a mantenere acquistare righe se

open_stock> 0, il che significa non c'è abbastanza azione per riempire l'ordine di vendita

e close_stock < 0 significato azioni dalla riga di acquisto tutte esaurite, o meno recenti (prima riga) dove close_stock> = 0, il che significa che l'acquisto da quella riga è parzialmente utilizzato.

  1. aggregato (prodotto di somma) prezzo e quantità per ottenere costo LIFO a passaggio 4.

Credo può essere facilmente modificato per LIFO e costo medio troppo.

--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