TSQL游标替代加速我的查询

时间:2014-02-03 15:49:41

标签: tsql sql-server-2008-r2

 Row Status  Time
 1   Status1 1383264075
 2   Status1 1383264195
 3   Status1 1383264315
 4   Status2 1383264435
 5   Status2 1383264555
 6   Status2 1383264675
 7   Status2 1383264795
 8   Status1 1383264915
 9   Status3 1383265035
 10  Status3 1383265155
 11  Status2 1383265275
 12  Status3 1383265395
 13  Status1 1383265515
 14  Status1 1383265535
 15  Status2 1383265615

[Time]列保留POSIX时间

我希望能够在不使用CURSORS的情况下计算给定时间段内给定[Status]活动的秒数。如果这是唯一那么好,因为我已经这样做了。

使用上面的示例数据提取,如何计算“Status1”已激活多长时间?

即,从Row1.[Time]中减去Row4.[Time],从Row8.[Time]减去Row9.[Time],从Row13.[Time]减去Row15.[Time]

提前谢谢

2 个答案:

答案 0 :(得分:2)

假设每一行表示特定Status从指定的Time激活到下一行,则必须以某种方式计算行N和N + 1之间的差异。一种方法是使用嵌套查询(在此处尝试:SQL Fiddle)。

SELECT SUM(Duration) as Duration
FROM (
  SELECT f.Status, s.Time-f.Time as Duration
  FROM Table1 f
  JOIN Table1 s on s.Row = f.Row+1
  WHERE f.Status = 'Status1') a

答案 1 :(得分:1)

如果Row值没有间隙,solution by @erikxiv将有效。如果他们确实存在差距,您可以尝试following method

SELECT
  TotalDuration = SUM(next.Time - curr.Time)
FROM
  dbo.atable AS curr
CROSS APPLY
  (
    SELECT TOP (1) Time
    FROM dbo.atable
    WHERE Row > curr.Row
    ORDER BY Row ASC
  ) AS next
WHERE
  curr.Status = 'Status1'
;

对于与指定状态匹配的每一行,CROSS APPLY子句中的相关子查询将根据Time的升序获取下一个Row值。然后从下一行的时间中减去当前行的时间,并使用SUM()将所有差异相加。

请注意,在两个解决方案中,暗示Row值的顺序遵循Time值的顺序。换句话说,假设ORDER BY Row等同于ORDER BY Time,或者如果Time可以有重复,则ORDER BY Time, Row