Как посчитать time-to-convert в SQL

Закрепи формулу time to convert в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать time to convert в Telegram

Зачем time-to-convert

Time-to-convert — время от первого касания до конверсии. У SaaS обычно 7–14 дней между signup и первой оплатой. Если медиана растёт — sales-цикл удлиняется, что-то ломается. Если ниже среднего по каналу — канал «горячий».

База в SQL

Простейший расчёт: signup → first purchase.

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';

Медиана и перцентили

Среднее можно искажают whales и outliers (юзер купил через год). Считают перцентили:

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;

Сравните organic vs paid: если paid даёт быстрее conversion — стоит увеличивать бюджет.

Закрепи формулу time to convert в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать time to convert в Telegram

Censored data

Юзер, который ещё не купил, не должен попасть в среднее (иначе подмёт ниже). Учитывайте «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 (survival analysis), но это уже сложнее.

Частые ошибки

Ошибка 1. Average на skewed данных. Распределение time-to-convert log-normal или Weibull. Медиана честнее среднего.

Ошибка 2. Игнорировать censoring. Юзер signup 2 дня назад, не купил — не значит, что time-to-convert = ∞. Это «ещё не наблюдалось».

Ошибка 3. Считать на чёткой INNER JOIN. users INNER JOIN orders отрезает не-converted — занижает данные. LEFT JOIN + дальнейшая фильтрация.

Ошибка 4. Не нормировать на cohort age. Юзеры из January 2026 имели 4 месяца для конверсии, May 2026 — 13 дней. Сравнение without truncation некорректно.

Ошибка 5. Округлять до дней слишком грубо. Для SaaS с trial и переходом в день 14 — округление до недель утратит сигнал.

Связанные темы

FAQ

Среднее или медиана?

Медиана. Среднее искажают outliers.

Что делать с не-конвертнувшими?

Survival analysis (Kaplan-Meier). Или анализ только на закрытых cohort'ах.

Time-to-convert vs sales cycle?

Sales cycle — обычно sales-team метрика (lead → deal). Time-to-convert — продуктовая (signup → first purchase).

Какая медиана нормальная?

SaaS B2C 1–7 дней, B2B 30–90 дней, e-com 0–3 дня.

По каналу разные медианы — что делать?

Канал с быстрой конверсией — масштабируем. Канал с долгой — переоцениваем CAC.