#sql #subquery #snowflake-cloud-data-platform #common-table-expression #window-functions
Вопрос:
Я работаю над созданием запроса для отслеживания жизненного цикла пользователя через платформу с помощью событий. Таблица EVENTS
содержит 3 столбца USER_ID, DATE_TIME и EVENT_NAME. Ниже приведен снимок таблицы,
Мой запрос должен возвращать следующий результат (первая метка времени для зарегистрированного события, за которой следует немедленная/следующая метка времени следующего события log_in и, наконец, за которой следует немедленная/следующая метка времени последнего события landing_page),
Ниже приведен мой запрос ,
WITH FIRST_STEP AS
(SELECT
USER_ID,
MIN(CASE WHEN EVENT_NAME = 'registered' THEN DATE_TIME ELSE NULL END) AS REGISTERED_TIMESTAMP
FROM EVENTS
GROUP BY 1
),
SECOND_STEP AS
(SELECT * FROM EVENTS
WHERE EVENT_NAME = 'log_in'
ORDER BY DATE_TIME
),
THIRD_STEP AS
(SELECT * FROM EVENTS
WHERE EVENT_NAME = 'landing_page'
ORDER BY DATE_TIME
)
SELECT
a.USER_ID,
a.REGISTERED_TIMESTAMP,
(SELECT
CASE WHEN b.DATE_TIME >= a.REGISTRATIONS_TIMESTAMP THEN b.DATE_TIME END AS LOG_IN_TIMESTAMP
FROM SECOND_STEP
LIMIT 1
),
(SELECT
CASE WHEN c.DATE_TIME >= LOG_IN_TIMESTAMP THEN c.DATE_TIME END AS LANDING_PAGE_TIMESTAMP
FROM THIRD_STEP
LIMIT 1
)
FROM FIRST_STEP AS a
LEFT JOIN SECOND_STEP AS b ON a.USER_ID = b.USER_ID
LEFT JOIN THIRD_STEP AS c ON b.USER_ID = c.USER_ID;
К сожалению, при попытке выполнить запрос я получаю ошибку «Ошибка компиляции SQL: Неподдерживаемый тип подзапроса не может быть оценен».
Ответ №1:
Это идеальный вариант использования для MATCH_RECOGNIZE
.
Шаблон, который вы ищете register anything* login anything* landing
, и меры min(iff(event_name='x', date_time, null))
для каждого из них одинаковы.
Проверять:
- https://towardsdatascience.com/funnel-analytics-with-sql-match-recognize-on-snowflake-8bd576d9b7b1
- https://docs.snowflake.com/en/user-guide/match-recognize-introduction.html
Установите для вывода значение one row per match
.
Непроверенный образец запроса:
select *
from data
match_recognize(
partition by user_id
order by date_time
measures min(iff(event_name='register', date_time, null)) as t1
, min(iff(event_name='log_in', date_time, null)) as t2
, min(iff(event_name='landing_page', date_time, null)) as t3
one row per match
pattern(register anything* login anything* landing)
define
register as event_name = 'register'
, login as event_name = 'log_in'
, landing as event_name = 'landing_page'
);
Комментарии:
1. ВЫБЕРИТЕ * ИЗ СОБЫТИЙ MATCH_RECOGNIZE( РАЗДЕЛ ПО ИДЕНТИФИКАТОРУ ПОЛЬЗОВАТЕЛЯ, ПОРЯДОК ПО ДАТАМ_ВРЕМЕНИ ИЗМЕРЯЕТ МИН(IFF(ИМЯ_СОБЫТИЯ=’зарегистрирован’, ДАТА_ВРЕМЕНИ, NULL)) КАК ОТМЕТКА ВРЕМЕНИ РЕГИСТРАЦИИ, МИН(IFF(ИМЯ_СОБЫТИЯ=’лог_ин’, ДАТА_ВРЕМЕНИ, NULL)) КАК ОТМЕТКА ВРЕМЕНИ РЕГИСТРАЦИИ, МИН(IFF(ИМЯ_СОБЫТИЯ=’посадка_времени’, ДАТА_ВРЕМЕНИ, NULL)) КАК ОТМЕТКА ВРЕМЕНИ ПОСАДКИ ПО ОДНОЙ СТРОКЕ НА ШАБЛОН СООТВЕТСТВИЯ(ШАГ_1 ШАГ_2 ШАГ_3) ОПРЕДЕЛИТЕ ШАГ_1 КАК ИМЯ СОБЫТИЯ= «зарегистрирован», ШАГ_2 КАК ИМЯ СОБЫТИЯ= «вход в систему», ШАГ_3 КАК ИМЯ СОБЫТИЯ=»посадочная страница» );
2. Есть ли способ изменить ШАБЛОН и ОПРЕДЕЛИТЬ логику или логику МЕР в запросе, чтобы получить то, что я хочу от своей таблицы (вернуть первую метку времени для первого события, за которой следует немедленная/следующая метка времени второго события, за которой следует немедленная/следующая метка времени третьего события и так далее в воронке)?
3. Количество записей в моем наборе результатов постоянно меняется, когда я каждый раз выполняю свой запрос
4. И как мы можем справиться с пропущенными событиями в потоке пользователя? если в потоке пользователей через воронку отсутствует какое-либо событие, запрос не возвращает никакого результата, так как поиск по шаблону завершается неудачно, когда определенное событие отсутствует в потоке пользователей
5. Отправьте новый вопрос с образцами данных и желаемыми результатами, и вы получите ответы, которые задают вопросы