🔥 Live Coding: покупка в течение 10 минут после логина

Задача: Есть таблица events:

• user_id • event_time • event_type

Типы событий: • login • purchase

Нужно найти пользователей, у которых покупка произошла в течение 10 минут после логина.

На выходе хотим получить:

• user_id • login_time • purchase_time

Решение:

with logins as ( select user_id, event_time as login_time from events where event_type = 'login' ),

purchases as ( select user_id, event_time as purchase_time from events where event_type = 'purchase' )

select l.user_id, l.login_time, min(p.purchase_time) as purchase_time from logins l inner join purchases p on l.user_id = p.user_id and p.purchase_time >= l.login_time and p.purchase_time <= l.login_time + interval 10 minute group by l.user_id, l.login_time

🧠 Как здесь думаем:

Мы разделяем события на 2 потока: • логины • покупки

Дальше джойним их по user_id.

Но просто соединить по пользователю недостаточно. Нам важно проверить время:

• purchase_time >= login_time • purchase_time <= login_time + interval 10 minute

То есть покупка должна быть: не раньше логина и не позже чем через 10 минут после него ✅

Почему берем min(p.purchase_time)? Потому что после одного логина у пользователя может быть несколько покупок. Обычно в такой задаче нам нужна ближайшая подходящая покупка после логина.

⚠️ Где можно ошибиться:

Не проверить, что покупка идет именно после логина

Если оставить только разницу во времени без условия purchase_time >= login_time, можно случайно захватить покупку, которая была раньше ❌

Получить дубли

После одного логина может быть несколько покупок в окне 10 минут. Если не сделать min() или другой явный выбор, получишь несколько строк на один login.

Перепутать бизнес-смысл

Эта версия запроса отвечает на вопрос: “была ли хотя бы одна покупка в течение 10 минут после логина?”

Если нужно искать строго первую покупку после логина, это уже отдельная логика.

💡 Более аккуратный вариант через оконную функцию:

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

with logins as ( select user_id, event_time as login_time from events where event_type = 'login' ),

purchases as ( select user_id, event_time as purchase_time from events where event_type = 'purchase' ),

matched as ( select l.user_id, l.login_time, p.purchase_time, row_number() over ( partition by l.user_id, l.login_time order by p.purchase_time ) as rn from logins l inner join purchases p on l.user_id = p.user_id and p.purchase_time >= l.login_time and p.purchase_time <= l.login_time + interval 10 minute )

select user_id, login_time, purchase_time from matched where rn = 1

🎯 Вывод:

Это типовая задача на поиск последовательности событий во времени.

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

Такая логика часто встречается в аналитике воронок, продуктовых сценариях и event-based задачах 📊

🔥 Live Coding: покупка в течение 10 минут после логина
Задача:
Есть таблица events:
• userid
• eventtime
• eventtype
Типы событий:
• login
• purchase
Нужно найти пользователей, у которых покупка произ... | Сетка — социальная сеть от hh.ru