這裏是樣本數據的表:TSQL - 遞歸CTE低效 - 需要一個替代
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列總是相同的,因爲它是在這個計算中只使用一次,但初始計算需要。
我試圖在第一行中從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項目Id的每個重複10次。如預期的那樣,它立即完成所有第一排計算,然後計算時間以DRASTICALLY遞增。
正如你所見,我已經嘗試了INNER JOIN
和CROSS JOIN
。我相信他們與我給出的參數CROSS JOIN
具有相同的執行計劃。
是否有更有效/更高效的方法來完成此操作?
我讓它在昨天運行了5個小時,看它是否結束..它沒有。
另一個注意事項:當我在測試數據上使用I SELECT
而不使用ORDER
希望有助於加快速度。 ORDER
只是爲了我的方便,當我實際檢查。
很肯定這是不確定的BY Main.ItemID作爲ItemID重複的Main.ItemID。 – Paparazzi
這真是一個更大的問題,一個沉悶的例子。實際上,我正在使用的數據中有另一列,將根據需要正確命令它。我只是不想渾濁的例子,因爲這使我在過去沒有答案 – jayEss
基於我的示例查詢的最高票數我假設這是最好的方式。我想我需要找到一種方法來索引數據樣本,希望能夠加快速度。任何人都可以解釋爲什麼這個計算需要這麼久嗎?我假設它與遞歸「循環」有關,它必須重新選擇每個ItemID的前一個數據集10次。 – jayEss