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

しかし、ご覧のとおり、在庫の 2 番目のロットが追加された後 (ID 4 の後) に間違った値が返されます。

現在、各レコードをループして現在の合計を保持する C# コードがあります。大型株の場合、これには非常に時間がかかります。唯一のオプションがカーソルを使用することである場合は、C# コードを保持します。

4

1 に答える 1

1

Randyが LAG 関数の使用について言及した後、SQL Server の LAG 関数を Google で簡単に検索したところ、テーブル変数と更新ステートメントを使用するコードが見つかりました。

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 に答える