Короткий ответ
Для таких воронок используют "любой порядок" (unordered/any-order funnel) — считают долю пользователей, совершивших все нужные события в заданном окне времени, независимо от последовательности, вместо строгой пошаговой (ordered) воронки, которая требует строгого соблюдения порядка шагов.
Как это работает подробнее
строгая (ordered) воронка требует, чтобы событие B произошло строго после события A для конкретного пользователя; any-order воронка просто проверяет наличие обоих событий в пределах окна, без требования к порядку — это ближе к реальному поведению, если у продукта нет жёстко навязанного сценария (например, пользователь может сначала добавить промокод, потом товар в корзину, или наоборот).
Пример кода
unordered_funnel.sql
-- PostgreSQL: any-order funnel за 24-часовое окно
WITH first_a AS (
SELECT user_id, MIN(event_time) AS t_a FROM events WHERE event_type='apply_promo' GROUP BY user_id
),
first_b AS (
SELECT user_id, MIN(event_time) AS t_b FROM events WHERE event_type='add_to_cart' GROUP BY user_id
)
SELECT COUNT(*) AS converted_any_order
FROM first_a a
JOIN first_b b ON a.user_id = b.user_id
WHERE ABS(EXTRACT(EPOCH FROM (a.t_a - b.t_b))) <= 86400;Что использовать на практике
- Практика. выбор между ordered и any-order воронкой должен определяться реальным продуктовым сценарием — для чётко последовательных процессов (checkout: адрес → оплата → подтверждение) строгий порядок важен и его нарушение может говорить об ошибке в данных; для более свободных сценариев (просмотр разных разделов перед покупкой) any-order честнее отражает поведение.
Подводные камни
- Частые ошибки. применяют строгую ordered-воронку к процессу, где порядок шагов на самом деле не важен, занижая реальную конверсию; не ограничивают окно времени в any-order воронке, из-за чего в конверсию попадают пары событий, разделённые месяцами и не связанные с одним и тем же "заходом" пользователя.