Как разбить поток событий на сессии на SQL?
- Как посчитать длительность сессии?
Сессия — серия событий пользователя без пауз дольше порога (обычно 30 минут). LAG даёт время предыдущего события; где пауза больше порога — флаг начала новой сессии; нарастающая сумма флагов по пользователю — номер сессии. Дальше агрегаты по (пользователь, номер сессии).
- Порог выбирают по распределению пауз, а не наугад
- Сессии, пересекающие полночь, не режут по датам
- Длительность сессии из одного события — ноль; это нужно учитывать в средних
А ещё Веб-аналитика (Яндекс Метрика, GA) определяет сессии по своим правилам — цифры могут не совпасть
Подробно
Выбор порога. Построить гистограмму пауз между соседними событиями пользователя: обычно видна «впадина» между короткими паузами внутри сессии и длинными между визитами. 30 минут — распространённое значение по умолчанию.
Тонкости: события с одинаковым временем — добавить второй ключ сортировки; события из разных устройств одного пользователя — решить, объединять ли; длительность считать до последнего события, а не до ухода — ухода мы не видим.
Пример
WITH marked AS (
SELECT user_id, event_time,
CASE WHEN event_time - LAG(event_time) OVER w > INTERVAL '30 minutes'
OR LAG(event_time) OVER w IS NULL THEN 1 ELSE 0 END AS new_session
FROM events
WINDOW w AS (PARTITION BY user_id ORDER BY event_time)
),
numbered AS (
SELECT *, SUM(new_session) OVER (PARTITION BY user_id ORDER BY event_time
ROWS UNBOUNDED PRECEDING) AS session_no
FROM marked
)
SELECT user_id, session_no,
MIN(event_time) AS started,
MAX(event_time) - MIN(event_time) AS duration,
COUNT(*) AS events
FROM numbered
GROUP BY user_id, session_no;Что хотят услышать
- Флаг новой сессии через LAG и нарастающую сумму.
- Выбор порога.
- Ограничения: последнее событие, устройства.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓LAG, флаг при паузе больше порога, нарастающая сумма флагов — номер сессии
- ✗Сессия — все события пользователя за календарный день: GROUP BY по user_id и дате события, а номер — ROW_NUMBER по дате
- ✗Порог паузы всегда ровно пять минут: так его определяет стандарт веб-аналитики
- ✗Сессии нужно резать по полуночи, иначе одна сессия попадёт сразу в два дня отчёта
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.