在庫計算のための加重平均コストを計算するために意図したとおりに動作する再帰的クエリがあります。私の問題は、異なる列でグループ化された同じクエリから複数の加重平均が必要なことです。問題をキー列ごとに1回ずつ計算して解決できることは分かっています。しかし、クエリのパフォーマンス上の考慮事項のために、私は一度それを横断したい。時には1M +行があります。再帰的クエリ(SQL Server)でグループ化された結果
私はデータを簡略化し、加重平均を単純な和に置き換えて、私の問題をより簡単に従わせました。
どのように再帰的なcteを使用して結果を得ることができますか?加重平均コストを計算するには再帰クエリを使用する必要があることを忘れないでください。 I(Idはまた、ソート順である。同上、キーが一緒にユニークである。)は、SQLサーバー上で午前2016
例データ
Id Key1 Key2 Key3 Value
1 1 1 1 10
2 1 1 1 10
3 1 2 1 10
4 2 2 1 10
5 1 2 1 10
6 1 1 2 10
7 1 1 1 10
8 3 3 1 10
期待される結果
Id Key1 Key2 Key3 Value Key1Sum Key2Sum Key3Sum
1 1 1 1 10 10 10 10
2 1 1 1 10 20 20 20
3 1 2 1 10 30 10 30
4 2 2 1 10 10 20 40
5 1 2 1 10 40 30 50
6 1 1 2 10 50 30 10
7 1 1 1 10 60 40 60
8 3 3 1 10 10 10 70
EDIT
よく批判を受けなければならないのですが、どうやって質問をするのかがはるかに良くなければなりません。
ここに例があります。なぜ再帰的なクエリが必要なのですか。この例ではKey1の結果が得られますが、同じクエリでKey2とKey3も必要です。私は同じクエリを3回繰り返すことができますが、それは好ましくありません。
DECLARE @InventoryItem AS TABLE (
IntentoryItemId INT NULL,
InventoryOrder INT,
Key1 INT NULL,
Key2 INT NULL,
Key3 INT NULL,
Quantity NUMERIC(22,9) NOT NULL,
Price NUMERIC(16,9) NOT NULL
);
INSERT INTO @InventoryItem (
IntentoryItemId,
InventoryOrder,
Key1,
Key2,
Key3,
Quantity,
Price
)
VALUES
(1, NULL, 1, 1, 1, 10, 1),
(2, NULL, 1, 1, 1, 10, 2),
(3, NULL, 1, 2, 1, 10, 2),
(4, NULL, 2, 2, 1, 10, 1),
(5, NULL, 1, 2, 1, 10, 5),
(6, NULL, 1, 1, 2, 10, 3),
(7, NULL, 1, 1, 1, 10, 3),
(8, NULL, 3, 3, 1, 10, 1);
--The steps below will give me the cost "grouped" by Key1
WITH Key1RowNumber AS (
SELECT
IntentoryItemId,
ROW_NUMBER() OVER (PARTITION BY Key1 ORDER BY IntentoryItemId) AS RowNumber
FROM @InventoryItem
)
UPDATE @InventoryItem
SET InventoryOrder = Key1RowNumber.RowNumber
FROM @InventoryItem InventoryItem
INNER JOIN Key1RowNumber
ON Key1RowNumber.IntentoryItemId = InventoryItem.IntentoryItemId;
WITH cte AS (
SELECT
IntentoryItemId,
InventoryOrder,
Key1,
Quantity,
Price,
CONVERT(NUMERIC(22,9), InventoryItem.Quantity) AS CurrentQuantity,
CONVERT(NUMERIC(22,9), (InventoryItem.Quantity * InventoryItem.Price)/NULLIF(InventoryItem.Quantity, 0)) AS AvgPrice
FROM @InventoryItem InventoryItem
WHERE InventoryItem.InventoryOrder = 1
UNION ALL
SELECT
Sub.IntentoryItemId,
Sub.InventoryOrder,
Sub.Key1,
Sub.Quantity,
Sub.Price,
CONVERT(NUMERIC(22,9), Main.CurrentQuantity + Sub.Quantity) AS CurrentQuantity,
CONVERT(NUMERIC(22,9),
((Main.CurrentQuantity) * Main.AvgPrice + Sub.Quantity * Sub.price)
/
NULLIF((Main.CurrentQuantity) + Sub.Quantity, 0)
) AS AvgPrice
FROM CTE Main
INNER JOIN @InventoryItem Sub
ON Main.Key1 = Sub.Key1
AND Sub.InventoryOrder = main.InventoryOrder + 1
)
SELECT cte.IntentoryItemId, cte.AvgPrice
FROM cte
ORDER BY IntentoryItemId
あなたは何を試してみましたか?つまり、どこに失われていますか? [最小限で完全で検証可能なサンプルを作成する方法](https://stackoverflow.com/help/mcve)を確認し、質問を修正してください。 – jhenderson2099
SQL Server 2012以降を使用している場合は、ウィンドウ関数を使用した方が再帰よりもパフォーマンスが向上する可能性があります。 –
最新の回答を確認してください。 – KumarHarsh