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

Проверь себя · 1/3разбор после ответа
В таблице users адрес электронной почты хранится в разном регистре: Anna@mail.ru, anna@MAIL.ru и т.д. Как надёжнее всего найти все записи с конкретным адресом вне зависимости от регистра?

Зачем GRR

GRR (Gross Revenue Retention) — это доля MRR, которую вы удержали, без учёта расширения (upsell и cross-sell). Он показывает «чистое» удержание: сколько денег осталось от исходной базы клиентов после оттока и сокращения подписок (downgrade). GRR всегда меньше NRR. Значение выше 90% считается здоровым для SaaS.

Формула

GRR = (starting_MRR - churn_MRR - contraction_MRR) / starting_MRR × 100%

Никогда не превышает 100% (в отличие от NRR).

GRR vs NRR

Метрика Учитывает расширение Может быть > 100%
GRR Нет Нет (максимум 100%)
NRR Да Да (у лучших > 120%)

GRR — чистый сигнал о качестве оттока и даунгрейдов. NRR — общее здоровье базы с учётом апселла.

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

WITH start AS (
    SELECT SUM(monthly_mrr) AS start_mrr
    FROM customers
    WHERE active_on = '2026-04-01'
),
churn_mrr AS (
    SELECT SUM(monthly_mrr) AS churned
    FROM customers
    WHERE active_on = '2026-04-01'
      AND churned_at BETWEEN '2026-04-01' AND '2026-05-01'
),
contraction AS (
    SELECT SUM(old_mrr - new_mrr) AS contracted_mrr
    FROM plan_changes
    WHERE change_at BETWEEN '2026-04-01' AND '2026-05-01'
      AND new_mrr < old_mrr
)
SELECT
    s.start_mrr,
    c.churned,
    co.contracted_mrr,
    (s.start_mrr - c.churned - co.contracted_mrr)::NUMERIC * 100 / NULLIF(s.start_mrr, 0) AS grr_pct
FROM start s, churn_mrr c, contraction co;
Закрепи формулу gross revenue retention в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать gross revenue retention в Telegram

По когортам

WITH cohort_start AS (
    SELECT
        DATE_TRUNC('month', first_paid_at) AS cohort,
        user_id,
        monthly_mrr AS start_mrr
    FROM customers
    WHERE first_paid_at >= '2025-06-01' AND first_paid_at < '2025-07-01'
),
cohort_now AS (
    SELECT
        cs.user_id,
        cs.cohort,
        cs.start_mrr,
        COALESCE(c.monthly_mrr, 0) AS current_mrr,
        CASE WHEN c.churned_at IS NOT NULL THEN cs.start_mrr ELSE 0 END AS churned_mrr,
        GREATEST(cs.start_mrr - COALESCE(c.monthly_mrr, 0), 0) - CASE WHEN c.churned_at IS NOT NULL THEN cs.start_mrr ELSE 0 END AS contraction_mrr
    FROM cohort_start cs
    LEFT JOIN customers c USING (user_id)
)
SELECT
    cohort,
    SUM(start_mrr) AS starting_mrr,
    SUM(churned_mrr) AS churn_mrr,
    SUM(contraction_mrr) AS contraction_mrr,
    (SUM(start_mrr) - SUM(churned_mrr) - SUM(contraction_mrr)) * 100.0 / SUM(start_mrr) AS grr_pct
FROM cohort_now
GROUP BY cohort;

Динамика GRR

WITH monthly AS (
    SELECT
        date_month,
        starting_mrr,
        churn_mrr,
        contraction_mrr,
        (starting_mrr - churn_mrr - contraction_mrr) * 100.0 / NULLIF(starting_mrr, 0) AS grr
    FROM mrr_snapshot
    WHERE date_month >= CURRENT_DATE - INTERVAL '12 months'
)
SELECT
    date_month,
    grr,
    AVG(grr) OVER (ORDER BY date_month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS grr_3m_avg
FROM monthly
ORDER BY date_month;

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

Ошибка 1. GRR > 100%. Математически невозможно. Где-то баг — скорее всего, в расчёт затесалось расширение (expansion).

Ошибка 2. Несогласованное окно. Месячный GRR не равен годовому. Зафиксируйте одно окно и считайте по нему.

Ошибка 3. Когорта против периода. Когортный GRR — это одна когорта во времени. Периодный GRR — все клиенты за конкретный месяц. Не путайте эти две метрики.

Ошибка 4. Определение сокращения. Понижение тарифа, уменьшение числа мест и применённая скидка — это разные вещи. Заранее зафиксируйте, что именно считаете сокращением (contraction).

Ошибка 5. Пауза/заморозка засчитана как отток. Клиент поставил подписку на паузу — считать это оттоком или нет? Определитесь и обрабатывайте такие случаи единообразно.

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

FAQ

Какой GRR считается нормальным?

Выше 90% — отличный показатель: клиентская база почти не тает. 85–90% — хороший уровень. Всё, что ниже 80%, — повод разбираться, потому что вы теряете заметную часть выручки на оттоке и даунгрейдах.

GRR или NRR — какая метрика важнее?

GRR отражает чистое удержание — насколько хорошо вы держите уже имеющуюся выручку. NRR показывает общий рост базы с учётом расширения (upsell). Обе метрики важны: GRR ловит проблемы с оттоком, а NRR — способность растить существующих клиентов.

GRR падает — что делать?

Сначала разберитесь в причинах оттока и даунгрейдов. Посмотрите когортный разрез, чтобы понять, какие именно клиенты уходят и когда. Часто помогают инвестиции в customer success — системную работу с удержанием существующих клиентов.

Как посчитать годовой GRR?

Можно возвести месячный GRR в 12-ю степень. Либо посчитать напрямую: (начальный MRR − отток − сокращение) / начальный MRR на 12-месячном окне.

Как учитывать паузу и заморозку подписки?

Если клиент поставил подписку на паузу и потом вернулся — это не отток. Если же пауза фактически бессрочная и клиент не возвращается, считайте её оттоком, как обычную отмену. Главное — обрабатывать все такие случаи одинаково.