TSQL не альтернативный курсор, чтобы ускорить мой запрос



 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



Я хочу иметь возможность вычислить количество секунд, в течение которых данный [Status] активен в течение данного периода времени, без использования курсоров. Если это единственное, то это прекрасно, так как я уже сделал это.

Используя приведенный выше пример извлечения данных, как мне вычислить, как долго" Status1 " был активен?



То есть вычесть Row1.[Time] из Row4.[Time], вычесть Row8.[Time] из Row9.[Time], вычесть Row13.[Time] из Row15.[Time].

Спасибо в продвижение

586   2  

2 ответов:

Решениепо @erikxiv будет работать, если значения Row не имеют пробелов. Если у них есть пробелы, вы можете попробовать следующий метод :

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.

Предполагая, что каждая строка представляет, что конкретный 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

Comments

    Ничего не найдено.