2012-06-26 51 views
5

这里有一个有趣的文章,我发现在我的项目有用:先入先出(FIFO)的库存成本

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

我们用它来跟踪的轨道运动

库存表进出我们想象中的库存仓库。我们的仓库最初是空的,然后股票因股票购买(tranCode ='IN')或由于随后的返回(tranCode ='RET')而进入仓库,并且当仓库移出仓库时它被出售(tranCode ='OUT')。每种类型的库存都通过ArticleID进行识别。由于某个商品的购买,销售或退货,库存内外的每次库存移动都会导致一行被添加到库存表中,由StockID标识列中的值唯一标识,并描述有多少项目被添加或删除,购买价格,交易日期等。

虽然我正在使用这个在我正在进行的项目上,但我一直坚持如何在每次交易的OUT上获得价格收费。我需要有这个价值来确定我会向客户收取多少费用。

  1. 首先增加5个苹果(各$ 10.00)的股票,共计$ 50.00

  2. 添加3个苹果(各$ 20.00美元)的股票共有8个苹果,为$ 110.00总价

  3. 然后拿出6项(5每$ 10.00 1每$ 20.00美元)$总共70个

  4. 它将离开2个苹果@每$ 20,总$ 40

  5. 012交易完成后

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”交易

+0

您需要为每个交易(In,Out,ret)赋予一个唯一的数字,以便您可以知道苹果的数量和价格。基于此,您可以通过计算(数量*价格)计算总计有多少。 –

+0

股票表中有一个主键。它只是我不想为了简单而显示它,我也使用ItemID而不是苹果。你不能仅仅通过计算(数量*价格)的价格孤单,记得我需要实现FIFO规则。 – samantha07

回答

0

价格如何构建具有表每个产品的每行一行,因此每个苹果的一行将随其价格和可用性(未售出/售出)一起插入。
然后您可以选择前n项,并选择与您需要的每种产品相关的价格。基本上,您只需创建一个项目队列,并从队列的前面(具有最早的插入日期)中删除那些“未售出”的项目。

+0

谢谢。这正是我的桌子正在做的。也许我没有明白你的观点,你能否给我一个例子? – samantha07

0

根据文章,脚本得到的结果是库存的价值。您需要修改此项,以便不计算所有库存,只使用前N个项目。

我会建议您使用CASE语句来设置每个'IN'中的物品数量,因为您知道库存物品和要取出的物品的数量,因此您可以检查物品的运行总量。

1

我建议设计你的餐桌如下: 在你的餐桌上添加一个新字段,即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_out”(用于交易)找到出价。

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

0

见下面的代码在TSQL。其基本思路是

  1. 每个销售行,说数量为数量,计算运行总销售额前的当前行,把它Previous_Sold。

  2. 对于步骤1中的每个销售行,找到所有以前的购买行并计算运行总库存UP购买,称之为Previous_Running_Stock。

  3. 在步骤2买方行,计算

Open_Stock = Previous_Running_Stock - Previous_Sold

Close_stock = Previous_Running_Stock - Previous_Sold - 数量。

  • 筛选,只保留购买行如果
  • open_stock> 0,意思是有足够的库存来填补卖出指令

    和close_stock < 0,意思购买行中的库存全部用完,或者最早(第一行),其中close_stock> = 0,这意味着部分使用该行中的采购。

  • 集合体(的总和产品)价格和数量以获得在步骤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