这基本上是一个库存项目,通过采购和销售分别跟踪物品的"入库"和"出库"。
库存系统遵循FIFO方法(首先购买的物品总是首先销售)。例如:
如果我们在1月、2月和3月购买了A物品 当顾客来时,我们会提供在1月购买的物品 仅当1月份物品用完后,我们才开始提供2月份的物品,以此类推。
因此,我必须在这里显示我手头的总库存和拆分,以便我可以看到所产生的总成本。
实际表格数据:
我需要获得的结果集:
我的客户坚持认为我不应该使用游标(Cursor),那么还有其他方法吗?
这基本上是一个库存项目,通过采购和销售分别跟踪物品的"入库"和"出库"。
库存系统遵循FIFO方法(首先购买的物品总是首先销售)。例如:
如果我们在1月、2月和3月购买了A物品 当顾客来时,我们会提供在1月购买的物品 仅当1月份物品用完后,我们才开始提供2月份的物品,以此类推。
因此,我必须在这里显示我手头的总库存和拆分,以便我可以看到所产生的总成本。
实际表格数据:
我需要获得的结果集:
我的客户坚持认为我不应该使用游标(Cursor),那么还有其他方法吗?
正如一些评论已经提到的,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
如果第二个“Item B”的价格有误(IN价格为25,OUT价格为35)。
SQL 2008 fiddle
仅供娱乐,使用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
更新
注意 -> 使用此处之前的两个查询需要数据按正确顺序排列。
如果要每天有多行细节,需要使用可靠的方法对具有相同日期的行进行排序,比如带有时间的日期列,自增ID或类似的方法。不能使用已经编写的查询,因为它们基于数据的位置。
更好的方法是将数据拆分为 IN 和 OUT,按项目、 wh 和日期排序,并在两个数据上应用 rank,如下所示:
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
但是,这个查询并不是完全可靠的,同一个顺序组内数据的顺序不稳定。
如果IN.price与OUT.price不同,我没有更改查询以重新计算价格。