Как посчитать time-to-convert в SQL
SELECT * FROM orders JOIN users ON orders.user_id = users.user_id и SELECT * FROM orders JOIN users USING(user_id). В чём ключевое ограничение USING?Содержание:
Зачем time-to-convert
Time-to-convert — время от первого касания до конверсии. У SaaS обычно 7–14 дней между регистрацией и первой оплатой. Если медиана растёт — цикл продаж удлиняется, что-то ломается. Если она ниже среднего по каналу — канал «горячий».
База в SQL
Простейший расчёт: регистрация → первая покупка.
WITH first_purchase AS (
SELECT
user_id,
MIN(created_at) AS first_purchase_at
FROM orders
GROUP BY user_id
)
SELECT
u.user_id,
u.created_at AS signup_at,
fp.first_purchase_at,
EXTRACT(EPOCH FROM (fp.first_purchase_at - u.created_at)) / 86400 AS days_to_convert
FROM users u
JOIN first_purchase fp USING (user_id)
WHERE u.created_at >= CURRENT_DATE - INTERVAL '90 days';Медиана и перцентили
Среднее искажают крупные плательщики и выбросы (пользователь купил через год). Поэтому считают перцентили:
SELECT
COUNT(*) AS converted_users,
AVG(days_to_convert) AS avg_days,
PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY days_to_convert) AS p25,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY days_to_convert) AS median,
PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY days_to_convert) AS p75,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY days_to_convert) AS p95
FROM time_to_convert_per_user;Медиана 3 дня, p95 = 30 дней — большинство быстро, хвост ходит долго.
По когортам и каналам
WITH base AS (
SELECT
u.user_id,
u.utm_source AS channel,
DATE_TRUNC('month', u.created_at)::DATE AS signup_month,
EXTRACT(EPOCH FROM (fp.first_purchase_at - u.created_at)) / 86400 AS days
FROM users u
JOIN first_purchase fp USING (user_id)
WHERE u.created_at >= CURRENT_DATE - INTERVAL '180 days'
)
SELECT
signup_month,
channel,
COUNT(*) AS converted,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY days) AS median_days
FROM base
GROUP BY signup_month, channel
HAVING COUNT(*) >= 30
ORDER BY signup_month, median_days;Сравните органику и платный трафик: если платный конвертит быстрее — стоит наращивать бюджет.
Цензурированные данные
Пользователь, который ещё не купил, не должен попадать в среднее (иначе занизит его). Учитывайте правостороннюю цензуру (right-censored):
WITH cohort AS (
SELECT
user_id,
created_at,
(SELECT MIN(created_at) FROM orders WHERE user_id = u.user_id) AS first_purchase_at
FROM users u
WHERE created_at >= '2026-01-01'
),
analysis AS (
SELECT
user_id,
first_purchase_at IS NOT NULL AS converted,
COALESCE(
EXTRACT(EPOCH FROM (first_purchase_at - created_at)) / 86400,
EXTRACT(EPOCH FROM (CURRENT_DATE - created_at)) / 86400
) AS time_observed
FROM cohort
)
SELECT
COUNT(*) FILTER (WHERE converted) AS converted_n,
COUNT(*) FILTER (WHERE NOT converted) AS still_observing_n,
AVG(time_observed) FILTER (WHERE converted) AS avg_among_converted_only
FROM analysis;Для строгого анализа — Kaplan–Meier (анализ выживаемости), но это уже сложнее.
Частые ошибки
Ошибка 1. Среднее на асимметричных данных. Распределение time-to-convert обычно логнормальное или Weibull. Медиана честнее среднего.
Ошибка 2. Игнорировать цензурирование. Пользователь зарегистрировался 2 дня назад и не купил — это не значит, что time-to-convert = ∞. Просто «ещё не наблюдалось».
Ошибка 3. Считать через голый INNER JOIN.
users INNER JOIN orders отрезает не сконвертившихся — и данные занижаются. Берите LEFT JOIN и фильтруйте дальше.
Ошибка 4. Не нормировать на возраст когорты. У пользователей из января 2026 было 4 месяца на конверсию, у майских — 13 дней. Сравнивать их без усечения окна некорректно.
Ошибка 5. Округлять до дней слишком грубо. Для SaaS с триалом и переходом на 14-й день округление до недель убьёт сигнал.
Связанные темы
- Как посчитать customer journey в SQL
- Как посчитать time-to-first-purchase в SQL
- Как посчитать time-to-value в SQL
- Как посчитать conversion-window в SQL
FAQ
Среднее или медиана?
Медиана. Распределение time-to-convert перекошено вправо: горстка пользователей, купивших спустя месяцы, тянет среднее вверх, и оно перестаёт описывать типичный срок. Медиана устойчива к таким выбросам и честнее отражает «сколько ждёт обычный пользователь».
Что делать с не сконвертившимися?
Правильный инструмент — анализ выживаемости (Kaplan–Meier): он корректно учитывает тех, кто ещё не купил, но может купить позже. Более простой вариант — считать только на закрытых когортах, у которых окно наблюдения уже полностью прошло.
Time-to-convert или цикл продаж?
Цикл продаж (sales cycle) — метрика отдела продаж: путь от лида до сделки. Time-to-convert — продуктовая метрика: от регистрации до первой покупки. Они считаются по разным событиям и живут в разных отчётах, путать их не стоит.
Какая медиана считается нормальной?
Зависит от типа продукта: у SaaS B2C это обычно 1–7 дней, у B2B — 30–90 дней, у e-commerce — 0–3 дня. Ориентир грубый: сравнивать всегда лучше со своей же прошлой когортой, а не с чужими бенчмарками.
По каналам разные медианы — что делать?
Канал с быстрой конверсией стоит масштабировать — он приводит уже прогретую аудиторию. По каналу с долгой конверсией пересмотрите CAC и окно окупаемости: деньги там возвращаются позже, и это надо закладывать в юнит-экономику.