Логика SQL-запросов жизненного цикла пользователя в Snowflake

#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)) для каждого из них одинаковы.

Проверять:

Установите для вывода значение 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. Отправьте новый вопрос с образцами данных и желаемыми результатами, и вы получите ответы, которые задают вопросы