7

这是一篇有趣的文章,我发现它对我的项目很有用:

基于集合的 Speed Phreakery:FIFO 库存 SQL 问题

库存表,我们使用它来跟踪库存进出我们想象的库存仓库的轨迹运动。我们的仓库最初是空的,然后由于库存购买 (tranCode = 'IN') 或由于后续退货 (tranCode = 'RET') 而库存移入仓库,当库存移出仓库时它已售出(tranCode = 'OUT')。每种类型的库存项目都由一个 ArticleID 标识。由于给定项目的购买、销售或退货,库存进出仓库的每次移动都会导致将一行添加到 Stock 表中,由 StockID 标识列中的值唯一标识,并描述有多少添加或删除项目、购买价格、交易日期等。

虽然我在我正在进行的项目中使用它,但我坚持如何让每笔交易“OUT”的收费。我需要有这个值来确定我将向我的客户收取多少费用。

  1. 首先在股票中添加 5 个苹果(每个 10.00 美元),总计 50.00 美元

  2. 将 3 个苹果(每个 20.00 美元)添加到 8 个苹果的库存中,总价格为 110.00 美元

  3. 然后取出 6 件商品(每件 10.00 美元 5 件,每件 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 个项目。本质上,您只是创建一个项目队列并从队列的前面(具有最早的插入日期)删除“未售出”的项目。

于 2012-06-26T21:08:22.173 回答
0

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

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

于 2012-12-04T05:22:16.863 回答
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

请参阅 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 回答