这是一篇有趣的文章,我发现在我的项目中很有用:
Set-based Speed Phreakery: The FIFO Stock Inventory SQL Problem:
我们用来跟踪库存进出虚拟库存仓库的轨道移动的库存表。我们的仓库最初是空的,然后库存由于库存购买(tranCode ='IN')或由于后续退货(tranCode ='RET')而进入仓库,当库存移出仓库时它被出售(tranCode ='OUT')。每种类型的库存都由ArticleID标识。由于购买,销售或返回给定物品,库存进出仓库的每次移动都会导致一行被添加到Stock表中,由StockID标识列中的值唯一标识,并描述了多少已添加或删除商品,购买价格,交易日期等。
虽然我在正在进行的项目中使用这个,但我坚持如何在每次交易'OUT'上获得价格。我需要有这个价值来确定我会向客户收取多少费用。
首先在库存中添加5个苹果(每个10.00美元),总计$ 50.00
将3个苹果(每个20.00美元)添加到8个苹果的库存中,总价格为110.00美元
然后拿出6件物品(5件每件10.00美元,每件1件20美元)总计70美元
交易完成后,将分别留下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'交易的价格
答案 0 :(得分: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”与“qty_out”(对于IN交易)进行比较,以找出价格。
答案 1 :(得分:0)
如何构建一个每个产品项目有一行的表格,因此每个苹果的行都会插入其价格和可用性(未售出/售出)。
然后,您只需选择前n项,并将价格与您想要的每种产品相关联。基本上,您只是创建一个项目队列,并从队列的前面(具有最早的插入日期)中删除那些“未售出”的项目。
答案 2 :(得分:0)
根据文章,脚本得到的结果是库存的价值。您需要对其进行修改,以便不使用所有库存计算,而只使用前N个项目。
我建议使用CASE语句来设置每个'IN'中的项目数,因为您知道了库存项目和要取出的数量,因此检查了运行总计。
答案 3 :(得分: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
答案 4 :(得分:0)
请参阅TSQL中的以下代码。基本理念是
对于每个卖出行,说数量是数量,计算当前行的运行总销售额,称之为Previous_Sold。
对于步骤1中的每个卖出行,找到所有PREVIOUS买入行,并计算出购买的最高库存量,称之为Previous_Running_Stock。
在步骤2中购买行,计算
Open_Stock = Previous_Running_Stock - Previous_Sold
Close_stock = Previous_Running_Stock - Previous_Sold - 数量。
open_stock> 0,表示有足够的库存来填充卖单
和close_stock< 0表示购买行中的库存全部用完,或者最早(第一行),其中close_stock> = 0,表示部分使用从该行购买。
我相信它很容易修改为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