Консолидация перекрывающихся периодов времени, сохраненных как время начала и окончания - PullRequest
0 голосов
/ 04 октября 2018

У меня есть таблица БД с двумя интересующими столбцами, первый - время начала (или включения), второй - время окончания (или выключения) для многочисленных событий в данной физической области.

Требованиеявляется идентифицировать уникальный период времени, в течение которого транспортное средство находилось в пределах области.Таким образом, начало первого события до конца последнего как непрерывный период.Количество включенных или выключенных событий в периоде не требуется для результирующей таблицы.

Существуют миллионы строк, поэтому объединение может вызвать проблемы из-за размера полученной таблицы.Я не против, но ...

Данные:

id          timeOn                    timeOff
761058840   2018-01-02 07:54:28.000   2018-01-02 08:33:34.000
761058840   2018-01-02 07:54:28.000   2018-01-02 08:36:30.000
761058840   2018-01-02 08:33:45.000   2018-01-02 08:35:30.000
761058840   2018-01-02 13:11:18.000   2018-01-02 13:14:04.000
761058840   2018-01-02 13:11:18.000   2018-01-02 13:39:40.000
761058840   2018-01-02 13:22:11.000   2018-01-02 13:40:25.000
761058840   2018-01-02 15:56:18.000   2018-01-02 15:59:34.000
761058840   2018-01-02 15:56:18.000   2018-01-02 16:36:25.000
761058840   2018-01-02 16:01:34.000   2018-01-02 16:05:34.000
761058840   2018-01-02 16:33:19.000   2018-01-02 16:38:26.000
761058840   2018-01-02 21:20:25.000   2018-01-02 21:24:25.000
761058840   2018-01-02 22:20:36.000   2018-01-03 05:20:37.000
761058840   2018-01-02 22:20:36.000   2018-01-03 05:20:37.000
761058840   2018-01-03 08:31:29.000   2018-01-03 09:01:10.000
761058840   2018-01-03 08:31:59.000   2018-01-03 09:01:07.000
761058840   2018-01-03 09:01:57.000   2018-01-03 09:06:27.000
761058840   2018-01-03 14:07:27.000   2018-01-03 14:17:32.000
761058840   2018-01-03 14:09:28.000   2018-01-03 14:45:00.000
761058840   2018-01-03 14:19:32.000   2018-01-03 14:48:22.000
761058840   2018-01-03 17:30:38.000   2018-01-03 18:06:35.000
761058840   2018-01-03 17:33:54.000   2018-01-03 18:09:48.000

Рассмотрим строки в этих данных, которые я ищу:

761058840   2018-01-02 07:54:28.000   2018-01-02 08:36:30.000
761058840   2018-01-02 13:11:18.000   2018-01-02 13:40:25.000
761058840   2018-01-02 15:56:18.000   2018-01-02 16:38:26.000
761058840   2018-01-02 21:20:25.000   2018-01-02 21:24:25.000
761058840   2018-01-02 22:20:36.000   2018-01-03 05:20:37.000
761058840   2018-01-03 08:31:59.000   2018-01-03 09:01:07.000
761058840   2018-01-03 09:01:57.000   2018-01-03 09:06:27.000
761058840   2018-01-03 14:07:27.000   2018-01-03 14:48:22.000
761058840   2018-01-03 17:30:38.000   2018-01-03 18:09:48.000

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

Кажется, что ничего не происходит для непрерывного времени.

БД - это SQL Server, поэтому T-SQL или ANSI были бы идеальными, но я готов к небольшому переводу.

(отредактируйте для пояснения: я пытаюсь объединить последовательность перекрывающихся времен от timeOn до timeOff в одну строку для каждой непрерывной последовательности)

1 Ответ

0 голосов
/ 04 октября 2018

Это классическая проблема слияния перекрывающихся интервалов .Самое простое решение - упорядочить данные по начальной точке и строкам группы, начинать новую группу каждый раз, когда вы обнаруживаете разрыв между макс.конечная точка над предыдущими и начальная точка текущей строки.

Следующее решение основано на этой идее (я использовал ROWS BETWEEN ... вместо LAG):

WITH t_with_change AS (
    SELECT id, timeOn, timeOff, CASE WHEN MAX(timeOff) OVER (PARTITION BY ID ORDER BY timeOn ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) >= timeOn THEN 0 ELSE 1 END AS chg
    FROM @t
), t_with_groups AS(
    SELECT id, timeOn, timeOff, SUM(chg) OVER (PARTITION BY ID ORDER BY timeOn) AS grp
    FROM t_with_change
)
SELECT id, grp, MIN(timeOn) AS timeOn, MAX(timeOff) AS timeOff
FROM t_with_groups
GROUP BY id, grp

DB Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...