Как посчитать Returning Users в SQL

Проверь себя · 1/3разбор после ответа
В отчёте нужно посчитать выручку по странам пользователей только по оплаченным заказам за период, причём шаг «оплаченные за период» используется ещё в трёх соседних метриках. Какой подход обычно делает запрос проверяемее и позволяет переиспользовать фильтрацию?

Зачем Returning Users

DAU 100K — вроде бы хорошо. Но: 70K новых, 30K вернувшихся. Через месяц новые падают (закончилась реклама), и DAU становится 30K. Доля вернувшихся — здоровый сигнал устойчивости бизнеса.

Что такое Returning

Returning User — активный за период, чья первая активность была ДО начала периода.

Returning ∈ period: first_activity < period_start AND has_activity_in_period

Базовый расчёт

WITH first_activity AS (
    SELECT user_id, MIN(event_date) AS first_date
    FROM events
    GROUP BY user_id
)
SELECT
    DATE_TRUNC('month', e.event_date) AS month,
    COUNT(DISTINCT CASE
        WHEN fa.first_date < DATE_TRUNC('month', e.event_date)
        THEN e.user_id
    END) AS returning_users,
    COUNT(DISTINCT CASE
        WHEN fa.first_date >= DATE_TRUNC('month', e.event_date)
         AND fa.first_date <  DATE_TRUNC('month', e.event_date) + INTERVAL '1 month'
        THEN e.user_id
    END) AS new_users,
    COUNT(DISTINCT e.user_id) AS total_active
FROM events e
JOIN first_activity fa ON fa.user_id = e.user_id
WHERE e.event_date >= '2026-01-01'
GROUP BY 1
ORDER BY 1;

Returning vs New vs Reactivated

Тип Определение
New Первая активность ∈ period
Returning Был активен сразу до period
Reactivated Был активен давно, потом был неактивен X+ дней, вернулся в period
WITH user_state AS (
    SELECT
        user_id,
        MIN(event_date) AS first_date,
        MAX(CASE WHEN event_date < '2026-04-01' THEN event_date END) AS last_before_period,
        MIN(CASE WHEN event_date >= '2026-04-01' AND event_date < '2026-05-01' THEN event_date END) AS first_in_period
    FROM events
    GROUP BY user_id
)
SELECT
    CASE
        WHEN first_date >= '2026-04-01' AND first_date < '2026-05-01' THEN 'new'
        WHEN last_before_period >= '2026-03-01' THEN 'returning'
        WHEN last_before_period IS NOT NULL THEN 'reactivated'
    END AS user_type,
    COUNT(*) AS users
FROM user_state
WHERE first_in_period IS NOT NULL
GROUP BY 1;
Закрепи формулу returning users в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать returning users в Telegram

Разрезы

По сегментам и каналам:

SELECT
    u.acquisition_channel,
    COUNT(DISTINCT CASE
        WHEN MIN(e.event_date) OVER (PARTITION BY e.user_id) < DATE_TRUNC('month', CURRENT_DATE)
        THEN e.user_id
    END) AS returning_users
FROM events e
JOIN users u ON u.user_id = e.user_id
WHERE e.event_date >= DATE_TRUNC('month', CURRENT_DATE)
GROUP BY u.acquisition_channel;

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

Ошибка 1. Returning = всё, что не new. В такой логике reactivated засчитывается как returning. Разделяйте эти группы.

Ошибка 2. Граничные случаи. Пользователь с first_date = period_start — это new или returning? Договоритесь заранее.

Ошибка 3. Разные устройства. Без единого user_id новое устройство засчитывается как «new». Учитывайте это.

Ошибка 4. NOT IN с NULL. Такой запрос ломается. Используйте NOT EXISTS.

Ошибка 5. Сравнение returning между периодами без нормализации. Пользователь в апреле — «returning», если был активен в марте. В мае он может стать «reactivated», если в апреле не заходил. Тип пользователя меняется от периода к периоду.

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

FAQ

Чем Returning отличается от Reactivated?

Returning — пользователь был активен недавно, в пределах порога неактивности. Reactivated — вернулся после долгого отсутствия.

Какая доля Returning считается хорошей?

Зависит от стадии роста. У стартапа в фазе бурного роста новых пользователей больше, чем вернувшихся. У зрелого продукта вернувшихся значительно больше, чем новых.

Returning DAU падает — что делать?

Скорее всего дело в удержании или вовлечённости. Разложите метрику по когортам и найдите, где именно теряете вернувшихся.

Учитывать разные устройства обязательно?

Желательно. Без объединения профилей вы завышаете число new и занижаете returning.

Returning стабильный, new упал — что делать?

Проблема в привлечении — в маркетинге или SEO. Сама база вернувшихся при этом здоровая, так что чинить нужно верх воронки.