这里是样本数据的表: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