我正在尝试编写SQL查询(SQL Server 2005)来计算库存的当前值。我有一张看起来像这样的表:
ID | QTY | BasePrice
1 | 10 | 100
2 | -2 | 0
3 | -2 | 0
4 | 10 | 200
5 | -2 | 0
其中qty> 0是股票进来和< 0是股票走出去。由于其他业务规则,负数量不记录BasePrice。基本价格是每单位价格。
我需要找到现有库存的平均价格或总价。因此,结果列必须是:
ID | QTY | BasePrice | TotalPrice | AveragePrice
1 | 10 | 100 | 1000 | 100
2 | -2 | 0 | 800 | 100
3 | -2 | 0 | 600 | 100
4 | 10 | 200 | 2600 | 162.50
5 | -2 | 0 | 2275 | 162.50
我能够解决这个问题:
select g1.projectionID,
g1.qty,
g1.basePrice,
((sum(isnull(g2.basePrice,0)))) * sum(isnull(g2.Qty,0)) + (g1.Qty * (case when g1.Qty < 0 THEN (sum(isnull(g2.basePrice,0))) ELSE g1.BasePrice END)) As CurrenctValueOfStockOnHand
from test g1
left join test g2 on g2.projectionID < g1.projectionID
group by g1.ProjectionID, g1.Qty, g1.BasePrice
给出了:
ID| QTY| BasePrice | TotalPrice
1 | 10 | 100.0000 | 1000.0000
2 | -2 | 0.0000 | 800.0000
3 | -2 | 0.0000 | 600.0000
4 | 10 | 200.0000 | 2600.0000
5 | -2 | 0.0000 | 4200.0000
但正如您所看到的,在添加第二批库存后(ID 4之后),它会给出错误的值。
我们目前有C#代码循环遍历每条记录并保持运行总计。对于大型股票而言,这需要太长时间。如果唯一的选择是使用游标,那么我们将保留我们的C#代码。
答案 0 :(得分:1)
在使用LAG功能提到Randy之后,我在SQL Server中快速搜索了LAG函数,并使用表变量和更新语句找到了代码。
declare @TempStocks TABLE (ProjectionID int, Qty Int, BasePrice Decimal (18,4), runningQty int, totalValueOfStockOnHand decimal(18,4))
insert into @TempStocks
select g1.*, sum(isnull(g2.Qty, 0)) + g1.Qty, 0
from gregTest g1
left join gregTest g2 on g2.projectionID < g1.ProjectionID
group by g1.ProjectionID, g1.BasePRice, g1.Qty
select * from @TempStocks
declare @CurrentValue Decimal (18,4)
set @CurrentValue = 0
update @TempStocks
set @CurrentValue = TotalValueOfStockOnHand = case when (Qty > 0) THEN (@CurrentValue + (BasePrice * Qty)) ELSE @CurrentValue + ((@CurrentValue / (RunningQty - qty) * Qty)) END
select *, TotalValueOfStockOnHand / RunningQty from @TempStocks
我仍然不相信这是最好的答案,但它确实在不使用光标的情况下提供了正确的输出