使用SQL在库存中实现FIFO

Har*_*ish 9 sql sql-server fifo

这基本上是一个库存项目,分别通过购买和销售跟踪项目的"库存"和"库存".

库存系统遵循FIFO方法(首先购买的物品总是先售出).例如:

如果我们在1月,2月和3月购买了商品A当客户到来时,我们只在1月份商品结束时赠送1月份购买的商品,我们开始赠送2月商品等等

所以我必须在这里显示我手中的总库存和拆分,以便我可以看到产生的总成本.

实际表格数据:

实际表数据

我需要获得的结果集:

结果集是什么意思

我的客户坚持认为我不应该使用Cursor,那么还有其他方法吗?

Ser*_*ton 12

正如一些评论已经说过,CTE可以解决这个问题

with cte as (
select item, wh, stock_in, stock_out, price, value
     , row_number() over (partition by item, wh order by item, wh) as rank
from   myTable)
select a.item, a.wh
     , a.stock_in - coalesce(b.stock_out, 0) stock
     , a.price
     , a.value - coalesce(b.value, 0) value
from cte a
     left join cte b on a.item = b.item and a.wh = b.wh and a.rank = b.rank - 1
where a.stock_in - coalesce(b.stock_out, 0) > 0
Run Code Online (Sandbox Code Playgroud)

如果第二个"项目B"的价格错误(IN价格为25,则OUT为35).
SQL 2008小提琴

只是为了好玩,使用sql server 2012和引入LEAD和LAG功能同样可以以更简单的方式实现

with cte as (
select item, wh, stock_in
     , coalesce(LEAD(stock_out) 
                OVER (partition by item, wh order by item, wh), 0) stock_out
     , price, value
     , coalesce(LEAD(value) 
                OVER (partition by  item, wh order by item, wh), 0) value_out
from   myTable)
select item
     , wh
     , (stock_in - stock_out) stock
     , price
     , (value - value_out) value
from   cte
where  (stock_in - stock_out) > 0
Run Code Online (Sandbox Code Playgroud)

SQL2012小提琴

更新
注意 - >要在此之前使用两个查询,数据需要按正确的顺序排列.

要使每天有超过一行的详细信息,您需要一些可靠的东西来订购具有相同日期的行,例如带有时间的日期列,自动增量ID或同一行的某些内容,并且不可能已经使用查询写的,因为它们是基于数据的位置.

更好的想法是将数据拆分为IN和OUT,按项目,wh和数据排序,并对两个数据应用排名,如下所示:

SELECT d_in.item
     , d_in.wh
     , d_in.stock_in - coalesce(d_out.stock_out, 0) stock
     , d_in.price
     , d_in.value - coalesce(d_out.value, 0) value
FROM   (SELECT item, wh, stock_in, price, value
             , rank = row_number() OVER 
               (PARTITION BY item, wh ORDER BY item, wh, date)
        FROM   myTable
        WHERE  stock_out = 0) d_in
       LEFT JOIN
       (SELECT item, wh, stock_out, price, value
             , rank = row_number() OVER 
               (PARTITION BY item, wh ORDER BY item, wh, date)
        FROM   myTable
        WHERE  stock_in = 0) d_out
       ON d_in.item = d_out.item AND d_in.wh = d_out.wh 
      AND d_in.rank = d_out.rank
WHERE d_in.stock_in - coalesce(d_out.stock_out, 0) > 0
Run Code Online (Sandbox Code Playgroud)

SQLFiddle

但是这个查询并不完全可靠,同一订单组中的数据顺序不稳定.

如果IN.price与OUT.price不同,我没有更改查询以重新计算价格