我有一個由時間戳值和絕對(米)值組成的數據集。有時儀表值重置爲零,這意味着我必須迭代並逐個計算增量,然後將其累加以獲得給定週期的總和。計算連續行之間的delta值的有效方法?
例如:
Timestamp Value
2009-01-01 100
2009-01-02 105
2009-01-03 120
2009-01-04 0
2009-01-05 9
這裏總爲29,計算公式爲:
(105 - 100) + (120 - 105) + (0) + (9 - 0) = 29
我使用MS-SQL服務器對於這一點,並開放給任何建議。
現在,我使用的是光標要做到這一點,它會檢查增量不爲負,然後合計起來:
DECLARE CURSOR curTest CURSOR FAST_FORWARD FOR
SELECT value FROM table ORDER BY timestamp
OPEN curTest
DECLARE @delta bigint, @current bigint, @last bigint
SET @delta = 0
FETCH curTest INTO @current
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@current IS NOT NULL) AND (@current > 0)
BEGIN
IF (@last IS NOT NULL) AND (@current > @last)
SET @delta = @delta + (@current - @last)
SET @last = @current
FETCH curTest INTO @current
END
END
CLOSE curTest
DEALLOCATE curTest
這將是很好得到一個數據集的像:
Timestamp Value LastValue
2009-01-01 100 NULL
2009-01-02 105 100
2009-01-03 120 105
2009-01-04 0 120
2009-01-05 9 0
因爲這將很容易抓住變化,爲(Value> LastValue)過濾,並做一個SUM()。
我想:
SELECT m1.timestamp, m1.value,
(SELECT TOP 1 m2.value FROM table WHERE m2.timestamp < m1.timestamp ORDER BY m2.timestamp DESC) as LastValue
FROM table
但其實這原來是比光標較慢:當我一起在SQL工作室與「節目的執行計劃」中運行這些,這樣做的相對成本100% (使用7或8次操作 - 時間戳中聚簇索引掃描的大多數),並且遊標爲0%(有3次操作)。 (我在這裏沒有簡單展示的是我有幾個不同的數字集合,在這個表格中還有一個外鍵 - 所以總是有一個WHERE子句限制到一個特定的集合。有幾個地方我一次計算給定時間段內的這些總數,因此它變成了相當的性能瓶頸,非遊標方法也可以很容易地修改爲GROUP BY鍵,並一次返回所有集合 - 但是在我的測試中,這實際上比運行光標多次要慢,因爲除了整體速度較慢外,還有額外的GROUP BY和SUM()操作開銷。)
1爲ROW_NUMBER的使用來計算() – 2009-08-13 04:19:45