Вычисление разницы во времени между двумя рядами при множественных вхождениях - PullRequest
0 голосов
/ 06 марта 2020

Я работаю над тем, что будет новой функцией, но я пытаюсь получить представление о том, как рассчитать разницу во времени между двумя строками каждый раз, когда появляется значение в двух других столбцах (prev_value, current_value). Затем разница будет заключена в сумму для окончательного значения по каждому идентификатору.

Пример ниже - небольшая часть таблицы, поэтому, если мы будем использовать идентификатор 194422, надеюсь, я смогу донести свою точку зрения.

Datediff, который я пытаюсь определить, будет между каждой записью, имеющей Current_Value 12026 и Prev_Value 12026. Таким образом, между верхними 2 строками, я бы ожидал 3-минутную разницу и между строками 3 и 4, я ожидал бы разницу в 4 минуты.

Если в строке есть значения current_value и prev_value 12026, я бы также включил это во время, поэтому в строке 13,14,15 я бы ожидал разницу в 9 минут между строками 13 и 15.

Затем я бы сгруппировал и суммировал эти результаты по идентификатору.

ROWID|  ID   | Columnname | prev_value |     current_value  |      OperationTime


1    |197684 |  STATUSID  |    1       |     12026          |     2020-02-11 13:37:00.0010
2    |197684 |  STATUSID  | 12026      |       1            |     2020-02-11 13:40:00.000
3    |197684 |  STATUSID  |    1       |     12026          |     2020-02-11 13:44:00.000
4    |197684 |  STATUSID  | 12026      |       1            |     2020-02-11 13:48:00.000
5    |198662 |  STATUSID  |    1       |     12026          |     2020-02-24 15:10:00.000
6    |198662 |  STATUSID  | 12026      |       1            |     2020-02-24 15:20:00.000
7    |198662 |  STATUSID  |    1       |     12026          |     2020-02-24 15:23:00.000
8    |198662 |  STATUSID  | 12026      |       1            |     2020-02-24 15:41:00.000
9    |198662 |  STATUSID  |    1       |     12026          |     2020-02-24 16:24:00.000
10   |198662 |  STATUSID  | 12026      |       1            |     2020-02-24 17:05:00.000
11   |194422 |  STATUSID  |    1       |     12026          |     2020-02-25 09:04:00.000
12   |194422 |  STATUSID  | 12026      |       8            |     2020-02-25 09:07:00.000
13   |198662 |  STATUSID  |    1       |     12026          |     2020-02-26 15:32:00.000
14   |198662 |  STATUSID  | 12026      |     12026          |     2020-02-26 15:40:00.000
15   |198662 |  STATUSID  | 12026      |       1            |     2020-02-26 15:41:00.000
16   |194422 |  STATUSID  |    1       |     12026          |     2020-03-02 16:06:00.000
17   |194422 |  STATUSID  | 12026      |       8            |     2020-03-02 16:15:00.000

В конечном итоге это будет:

      RowID |  TimeSpent(Mins)

    194422  |     9
    197684  |     7
    198662  |     78

Я сейчас попробовал несколько различных методов, но записи либо отсутствуют, либо извлекаются неверные времена.

Я смотрел на CTE с INNER и LEFT JOIN и OUTER JOIN обратно на CTE, я пробовал два CTE, я смотрел на LAG, RANK и ROW_NUMBER () во всех примерах.

Сценарий, приведенный ниже, работает, но он не учитывает все мои результаты, и в этом примере он пропускает идентификатор 194422.

DECLARE @STATUSID INT 
SET @STATUSID = 12026 

;WITH CTE
     AS (SELECT prev_value, 
                current_value, 
                OPERATIONTIME,
                ROWID,
                ID,
            DENSE_RANK () OVER (PARTITION BY prev_value ORDER BY operationtime) AS ROWNUMBER  
         FROM   AUDITREVIEW
         WHERE  columnname = 'STATUSID' 
                AND ( current_value = @STATUSID 
                       OR prev_value = @STATUSID )    
                ) 

SELECT *,
    DATEDIFF(MINUTE,  CTE2.cte2OPERATIONTIME, CTE1.operationtime) as t
    INTO #Temp
FROM 
    CTE AS CTE1
OUTER APPLY 
        (SELECT  top 1
           prev_value as cte2prev_value, 
                current_value cte2current_value, 
                OPERATIONTIME cte2OPERATIONTIME,
                ROWID cte2rowID,
                ID cte2ID,
                DENSE_RANK () OVER ( ORDER BY operationtime) AS cte2ROWNUMBER 
            FROM CTE 
            WHERE CTE.ID = CTE1.ID 
            AND CTE.PREV_VALUE = CTE1.CURRENT_VALUE
            AND CTE.ROWNUMBER < CTE1.ROWNUMBER
            ORDER BY CTE.OPERATIONTIME DESC
            ) CTE2

--WHERE CTE1.WORKORDERID = 194422


SELECT SUM(t), ID
FROM #Temp
WHERE cte2prev_value <> @STATUSID
GROUP BY ID

DROP TABLE #Temp

1 Ответ

0 голосов
/ 06 марта 2020

попробуйте следующее:

SELECT a1.ID, 
       SUM(DATEDIFF(MINUTE, a1.OperationTime, a2.OperationTime)) Time_Spent_in_Minutes
FROM AUDITREVIEW a1
     JOIN AUDITREVIEW a2 ON a2.ID = a1.ID
                            AND ((a1.ROWID = a2.ROWID)
                                 OR (a1.ROWID + 1 = a2.ROWID))
WHERE(a1.current_value = 12026 AND a2.prev_value = 12026)
     AND ((a1.prev_value = 1 AND a2.current_value = 1)
          OR (a1.current_value = 12026 AND a1.prev_value = 12026)
          OR (a2.current_value = 12026 AND a2.prev_value = 12026))
GROUP BY a1.ID
ORDER BY 1;

db <> fiddle demo

...