2

我正在尝试编写一个 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# 代码。

4

1 回答 1

1

Randy提到使用 LAG 函数之后,我在 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

我仍然不相信这是最好的答案,但它确实在不使用光标的情况下给出了正确的输出

于 2012-06-06T03:30:24.743 回答