サンプルデータの表は次のとおりです。
DECLARE @TestTable TABLE (
ItemID INT,
A INT,
B INT,
Month INT)
INSERT INTO @TestTable VALUES (1234, 5, 9, 1)
INSERT INTO @TestTable VALUES (1234, 6, 9, 2)
INSERT INTO @TestTable VALUES (4321, 5, 11, 1)
INSERT INTO @TestTable VALUES (4321, 12, 11, 2)
INSERT INTO @TestTable VALUES (1324, 14, 6, 1)
INSERT INTO @TestTable VALUES (1324, 5, 6, 2)
INSERT INTO @TestTable VALUES (1234, 1, 9, 3)
INSERT INTO @TestTable VALUES (1324, 9, 6, 3)
注意すべき点は、B列は、この計算で1回だけ使用されるのと常に同じですが、最初の計算に必要なことです。
最初の行でAからBを減算し、次に後続の行でAから前の行の差を減算しようとしています。事実上、最初の行で、次にB - A = C
関連C - A
するItemIDのすべての後続の行で。
これが私が期待している結果です:
ItemID A B C Month RowNumber
1234 5 9 4 1 1
1234 6 9 -2 2 2
1234 1 9 -3 3 3
1324 14 6 -8 1 1
1324 5 6 -13 2 2
1324 9 6 -22 3 3
4321 5 11 6 1 1
4321 12 11 -6 2 2
これが私がこれを達成する方法です。
;WITH CTE_TestValue AS (
SELECT
Main.ItemID,
Main.A,
Main.B,
Main.Month,
ROW_NUMBER() OVER (Partition BY Main.ItemID ORDER BY Main.Month) AS RowNumber
FROM @TestTable AS Main
),
CTE_TestColumnC AS (
SELECT
MainA.ItemID,
MainA.A,
MainA.B,
(MainA.B - MainA.A) AS C,
MainA.Month,
MainA.RowNumber
FROM CTE_TestValue AS MainA
WHERE MainA.Rownumber = 1
UNION ALL
SELECT
MainB.ItemID,
MainB.A,
MainB.B,
(Sub.C - MainB.A) AS C,
MainB.Month,
MainB.RowNumber
FROM CTE_TestValue AS MainB
INNER JOIN CTE_TestColumnC AS Sub
ON MainB.RowNumber - 1 = Sub.RowNumber
AND MainB.ItemID = Sub.ItemID
-- CROSS JOIN CTE_TestColumnC AS Sub
-- WHERE Sub.RowNumber + 1 = MainB.RowNumber
-- AND MainB.ItemID = Sub.ItemID
)
SELECT
Main.ItemID,
Main.A,
Main.B,
Main.C,
Main.Month,
Main.RowNumber
FROM CTE_TestColumnC AS Main
ORDER BY ItemID, Month, RowNumber
これは小さなデータサンプルでは問題なく機能しますが、私はそれぞれ約20,000個のItemIdを10回繰り返し処理しています。予想どおり、最初の行のすべての計算が即座に終了し、計算時間が大幅に増加します。
ご覧のとおり、私はとの両方を試しましINNER JOIN
たCROSS JOIN
。彼らは私が与えたパラメータで同じ実行計画を持っていると思いますCROSS JOIN
。
これを達成するためのより効果的/効率的な方法はありますか?
昨日これを5時間実行して、終了したかどうかを確認しました。終了しませんでした。
別の注意:これをテストデータで使用しているときは、うまくいけばスピードアップに役立てるためにSELECT
使用していません。ORDER
ファクトチェックをしているときの便宜のORDER
ためです。