Как показать временные диапазоны в t- sql, где есть перерыв во времени - PullRequest
0 голосов
/ 30 января 2020

В настоящее время я наблюдаю за использованием устройства. Таким образом, каждую минуту, когда устройство используется, оно делает запись в журнале на моем sql сервере. Будут перерывы в потоке времени, когда устройство не используется. Есть ли способ заставить вывод отображать что-то вроде

01/01/2020 10:01 - 01/01/2020 10:14
01/01/2020 13:15 - 01/01/2020 13:26

Ниже приведено изображение того, как мои данные выглядят прямо сейчас.

Image of time output now

1 Ответ

1 голос
/ 30 января 2020

Вы можете использовать оконную функцию T SQL LEAD () , чтобы получить следующую временную метку.

DROP TABLE IF EXISTS #dataset ;

-- USE Recursive CTE to create a Table #dataset that we can work with
WITH cte 
  AS (
      SELECT GETUTCDATE() AS [DateTime], 1 AS counters, 'device-1' AS device_name
      UNION ALL
      SELECT
          -- Cause a Break at 10th and 15th row
          IIF(cte.counters IN ( 10, 15 ), DATEADD( MINUTE, 10, cte.[DateTime] ), DATEADD( MINUTE, 1, cte.[DateTime] ))
        , 1 + cte.counters
        , cte.device_name
      FROM cte
      WHERE cte.counters < 20
)
SELECT * 
INTO #dataset 
FROM cte ;


-- Now that we have a TestDataSet - Let us Query 
SELECT
    [DateTime]
  , device_name
  , LEAD( [DateTime] ) OVER (PARTITION BY device_name ORDER BY [DateTime]) AS next_DateTime
  , CASE
         -- LEAD( [DateTime] ) OVER (PARTITION BY device_name ORDER BY [DateTime]) is what the next time now 
         WHEN DATEDIFF( MINUTE, [DateTime], LEAD( [DateTime] ) OVER (PARTITION BY device_name ORDER BY [DateTime])) > 1 /*Tollerance*/ THEN
             'break'
         ELSE 'ok' END AS break_check_code
FROM #dataset ;

Используя Lead LEAD( DateTime ) OVER (PARTITION BY device_name ORDER BY DateTime), мы просим следующий DateTime из device_name (PARTITION BY), управляющий этим, и затем мы определяем порядок, используя ORDER BY

Теперь, когда мы можем получить следующее DateTime устройства, мы можем использовать некоторые CASE и DATEDIFF, чтобы проверить, какова разница во времени между текущей меткой времени и следующей.

Это приведет к следующему

|DateTime               |device_name|next_DateTime          |break_check_code|
|2020-01-30 17:00:19.483|device-1   |2020-01-30 17:01:19.483|ok              |
|2020-01-30 17:01:19.483|device-1   |2020-01-30 17:02:19.483|ok              |
|2020-01-30 17:02:19.483|device-1   |2020-01-30 17:03:19.483|ok              |
|2020-01-30 17:03:19.483|device-1   |2020-01-30 17:04:19.483|ok              |
|2020-01-30 17:04:19.483|device-1   |2020-01-30 17:05:19.483|ok              |
|2020-01-30 17:05:19.483|device-1   |2020-01-30 17:06:19.483|ok              |
|2020-01-30 17:06:19.483|device-1   |2020-01-30 17:07:19.483|ok              |
|2020-01-30 17:07:19.483|device-1   |2020-01-30 17:08:19.483|ok              |
|2020-01-30 17:08:19.483|device-1   |2020-01-30 17:09:19.483|ok              |
|2020-01-30 17:09:19.483|device-1   |2020-01-30 17:19:19.483|break           |
|2020-01-30 17:19:19.483|device-1   |2020-01-30 17:20:19.483|ok              |
|2020-01-30 17:20:19.483|device-1   |2020-01-30 17:21:19.483|ok              |
|2020-01-30 17:21:19.483|device-1   |2020-01-30 17:22:19.483|ok              |
|2020-01-30 17:22:19.483|device-1   |2020-01-30 17:23:19.483|ok              |
|2020-01-30 17:23:19.483|device-1   |2020-01-30 17:33:19.483|break           |
|2020-01-30 17:33:19.483|device-1   |2020-01-30 17:34:19.483|ok              |
|2020-01-30 17:34:19.483|device-1   |2020-01-30 17:35:19.483|ok              |
|2020-01-30 17:35:19.483|device-1   |2020-01-30 17:36:19.483|ok              |
|2020-01-30 17:36:19.483|device-1   |2020-01-30 17:37:19.483|ok              |
|2020-01-30 17:37:19.483|device-1   |NULL                   |ok              |

См. SQL Fiddle для запуска этого примера

...