考虑以下查询...
SELECT
*
,CAST(
(CurrentSampleDateTime - PreviousSampleDateTime) AS FLOAT
) * 24.0 * 60.0 AS DeltaMinutes
FROM
(
SELECT
C.SampleDateTime AS CurrentSampleDateTime
,C.Location
,C.CurrentValue
,(
SELECT TOP 1
Previous.SampleDateTime
FROM Samples AS Previous
WHERE
Previous.Location = C.Location
AND Previous.SampleDateTime < C.SampleDateTime
ORDER BY Previous.SampleDateTime DESC
) AS PreviousSampleDateTime
FROM Samples AS C
) AS TempResults
假设所有事物都相同,例如索引等,这是实现上述结果的最有效方法吗?那是使用 SubQuery 来检索最后一条记录?
我最好创建一个按位置排序的游标,SampleDateTime 并为 CurrentSampleDateTime 和 PreviousSampleDateTime 设置变量...在 while 循环的底部将 Previous 设置为 Current?
我对 CTE 不是很好,这可以通过 CTE 更有效地完成吗?如果是这样,那会是什么样子?
我可能必须检索 PreviousValue 以及 Previous SampleDateTime 以获得两者的平均值。这是否会改变结果。
长话短说,如果您需要在当前记录的计算中使用这些值,那么保持先前记录值的最佳/最有效方法是什么?
----更新我应该注意,我在 Location、SampleDateTime、CurrentValue 上有一个聚集索引,所以这可能是影响结果的最重要因素。
有 5,591,571 条记录,我的查询(上面的那个)平均需要 3 分 20 秒
低于 Joachim Isaksson 的 CTE 平均需要 5 分 15 秒。
也许它需要更长的时间,因为它没有使用聚集索引,而是使用行号进行连接?
我开始测试游标方法,但它已经在 10 分钟......所以不要继续那个。
我会给它一天左右的时间,但我认为我会接受 Joachim Isaksson 提供的 CTE 答案,因为我找到了一种获得最后一行的新方法。
谁能同意是 Location、SampleDateTime、CurrentValue 上的索引使子查询方法更快?
我没有 SQL Server 2012,所以无法测试 LEAD/LAG 方法。我敢打赌,假设微软有效地实现了这一点,那将比我尝试过的任何事情都要快。可能只需要在每行末尾交换指向内存引用的指针。