这基本上是一个库存项目,分别通过购买和销售跟踪物品的“库存”和“库存”。
库存系统遵循FIFO方法(首先购买的物品总是先出售)。例如:
如果我们在1月,2月和3月购买了商品A. 当顾客到来时,我们会赠送1月份购买的商品 只有当1月份的项目结束时,我们才会开始赠送2月份的物品等等
所以我必须在这里显示我手中的总库存和拆分,以便我可以看到所产生的总成本。
实际表格数据:
我需要获得的结果集:
我的客户坚持认为我不应该使用Cursor,那么还有其他方法吗?
答案 0 :(得分: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
如果第二个“项目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
<强>更新强>
注意 - &gt;要在此点之前使用两个查询,数据需要按正确的顺序排列。
要获得每天多于一行的详细信息,您需要一些可靠的东西来订购具有相同日期的行,例如带有时间的日期列,自动增量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
但是此查询 NOT 完全可靠,同一订单组中的数据顺序不稳定。
如果IN.price与OUT.price不同,我没有更改查询以重新计算价格
答案 1 :(得分:2)
如果游标不是一个选项,则可能是SQLCLR stored procedure。这样,您可以将原始数据获取到.net个对象,使用c#或vb.net对其进行操作/排序,并将结果数据设置为过程的输出。不仅这会给你你想要的东西,它甚至比在纯T-SQL中尝试做同样容易,这取决于你的编程背景。