КПКейсПрактика
Все материалы
Продуктовая аналитикапрактикумсредний

Как посчитать воронку в SQL: шаги, конверсия и drop-off

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

КПКейсПрактика18 июля 2026 г.10 мин
Аналитики показывают последовательность ступеней воронки и уменьшение числа пользователей на каждом этапе.

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

Коротко

Воронка — это последовательность шагов от входа в сценарий до целевого действия. Для каждого шага считаем уникальных пользователей, затем сравниваем соседние уровни. Конверсия шага и общая конверсия — разные показатели, поэтому их нельзя подписывать одним словом “conversion”.

  • Сначала назови событие каждого шага и его grain.
  • Для пользователей используй `COUNT(DISTINCT user_id)`.
  • Локальная конверсия шага считается от предыдущего шага.
  • Общая конверсия считается от первого шага воронки.
  • Проверь порядок событий и временное окно между шагами.

Определи воронку до SQL

Возьмём сценарий SaaS-продукта: пользователь открыл приложение, создал проект, пригласил коллегу и выполнил core action. Один и тот же человек может повторять события, поэтому шаг воронки — это не количество строк в events, а факт того, что пользователь выполнил условие.

Пример воронки активации
ШагСобытиеЧто означает
1. Входapp_openпользователь начал сценарий
2. Проектproject_createdсоздал рабочий объект
3. Командаinvite_sentпригласил коллегу
4. Ценностьcore_actionвыполнил основное действие
Пример потерь между шагами

Числа иллюстративные: в рабочем расчёте их нужно получить из событий с согласованным окном.

Вход100% от входа
Проект62% от входа
Команда28% от входа
Ценность17% от входа

Базовый запрос: пользователи на каждом шаге

Если нужен быстрый обзор, можно посчитать уникальных пользователей, которые когда-либо совершили каждое событие в выбранном периоде. Такой запрос отвечает на вопрос “сколько людей дошло до каждого типа действия”, но ещё не доказывает, что шаги были пройдены в правильной последовательности.

Размер шагов воронки за период
select
  event_name,
  count(distinct user_id) as users_count
from events
where event_date >= date '2026-06-01'
  and event_date < date '2026-07-01'
  and event_name in (
    'app_open',
    'project_created',
    'invite_sent',
    'core_action'
  )
group by event_name
order by users_count desc;
Не называй это последовательной воронкой

Один пользователь мог выполнить core_action до app_open из выбранного периода или сделать шаги в другом сценарии. Для строгой воронки нужно проверить порядок и временную близость событий.

Последовательная воронка через первые даты

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

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

Пользователи, прошедшие шаги в правильном порядке
with first_steps as (
  select
    user_id,
    min(event_date) filter (where event_name = 'app_open') as opened_at,
    min(event_date) filter (where event_name = 'project_created') as project_at,
    min(event_date) filter (where event_name = 'invite_sent') as invite_at,
    min(event_date) filter (where event_name = 'core_action') as core_at
  from events
  group by user_id
),
ordered_users as (
  select *
  from first_steps
  where opened_at is not null
    and project_at > opened_at
    and invite_at > project_at
    and core_at > invite_at
)
select
  count(*) as completed_funnel_users
from ordered_users;

Локальная и общая конверсия

Пусть воронка имеет 10 000 входов, 6 200 проектов, 2 800 приглашений и 1 700 core actions. Конверсия вход → проект равна 62%, проект → приглашение — 45%, приглашение → ценность — 61%. Общая конверсия от входа до ценности — 17%. Эти числа отвечают на разные вопросы.

Две конверсии
step_conversion = users_at_step / users_at_previous_step; total_conversion = users_at_step / users_at_first_step

Знаменатель нужно писать рядом с метрикой в отчёте, иначе один процент легко принять за другой.

Как читать провал между шагами
ПоказательФормулаВопрос
Локальная конверсияstep N / step N-1Где ломается ближайший переход?
Общая конверсияstep N / step 1Сколько входов дошло до цели?
Drop-off1 - local conversionКакая доля потерялась на переходе?

Окно между шагами меняет ответ

Воронка без временного окна может засчитать старое событие как часть нового сценария. Например, пользователь создал проект три месяца назад, а core action выполнил сегодня. Для онбординга это не тот же самый проход. Договорись, должен ли следующий шаг произойти в течение часа, дня или семи дней после предыдущего.

Сегментируй до интерпретации

Один общий drop-off может скрывать разные сценарии. Сравни воронку по платформе, каналу, новой когорте и типу пользователя, но сначала убедись, что события одинаково трекаются в каждом сегменте.

  • События одной сессии — узкое окно для коротких сценариев.
  • 24 часа — часто разумный старт для активации.
  • 7 или 14 дней — вариант для длинного B2B-онбординга.
  • Слишком широкое окно смешивает разные попытки пользователя.
  • Слишком узкое окно записывает нормальную задержку как потерю.

Ошибки в SQL-воронках

Воронка особенно чувствительна к определению события. Технический `page_view` может дать красивый первый шаг, но не сказать, что пользователь действительно начал работу. Поэтому проверяй не только запрос, но и смысл событий в продукте.

  • Считать события вместо уникальных пользователей.
  • Использовать разные периоды для разных шагов.
  • Не фиксировать порядок событий и временное окно.
  • Сравнивать локальную конверсию одного шага с общей конверсией другого.
  • Менять определение шага посреди эксперимента и сравнивать несопоставимые периоды.
  • Делать вывод по маленькому сегменту без показа его размера.

Мини-практика и следующий шаг

Собери в тренажёре простую воронку app_open → core_action. Сначала посчитай уникальных пользователей по типу события, затем добавь проверку порядка через первые даты. После этого сравни локальную конверсию и drop-off по каждому переходу.

Продолжить чтение
Вся библиотека