Моя таблица заполнена событиями из внешнего источника, такими как:
SELECT target_type, timer_type, event_happened_at
FROM tracked_events
ORDER BY event_happened_at ASC;
TARGET_TYPE TIMER_TYPE EVENT_HAPPENED_AT
"JOB", "START", "2018-11-06 06:00:00+00"
"JOB", "STOP", "2018-11-06 10:30:00+00"
"PAUSE", "START", "2018-11-06 10:30:00+00"
"PAUSE", "STOP", "2018-11-06 11:00:00+00"
"JOB", "START", "2018-11-06 11:00:00+00"
"JOB", "STOP", "2018-11-06 15:00:00+00"
Мы можем видеть логическую группировку в три строки:
TYPE START END
JOB, 2018-11-06 06:00:00+00, 2018-11-06 10:00:00+00
PAUSE, 2018-11-06 10:00:00+00, 2018-11-06 11:00:00+00
JOB, 2018-11-06 11:00:00+00, 2018-11-06 15:00:00+00
Я пытаюсь найти хороший способ выполнить эту группировку в SQL. Типы событий предопределены и гарантированно будут отправлены «логическим способом» (то есть PAUSE / START не произойдет до JOB / END., И начало / конец гарантированно будут существовать для всех событий.)
Так что, по сути, если я вижу JOB / START, мне нужно найти следующую JOB / END, и в равной степени для PAUSE / START to PAUSE / END.
Я вижу запрос, в котором я только ищу события START и выполняю подзапрос, чтобы найти соответствующий ему КОНЕЦ:
WITH starts AS (
SELECT session_id, target_type, timer_type, event_happened_at
FROM received_session_events
WHERE session_id = 266
AND TIMER_TYPE = 'START'
ORDER BY event_happened_at ASC
)
SELECT target_type, event_happened_at AS started_at,
(
SELECT event_happened_at
FROM received_session_events end_event
WHERE session_id = starts.session_id
AND timer_type = 'STOP' AND end_event.target_type = starts.target_type
AND end_event.event_happened_at > starts.event_happened_at
ORDER BY event_happened_at ASC
LIMIT 1
) AS ended_at
FROM starts
Это работает, дает правильный результат, но что-то кажется неэффективным и неуместным. Добавление индексов - это вариант, который я еще не исследовал (и при этом я не знаю, с чего начать, кроме очевидных, появляющихся в предложениях WHERE.)