Как посчитать NPS в SQL
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Зачем аналитику считать NPS в SQL
NPS (Net Promoter Score) — главная метрика лояльности в продукте. Простой вопрос «насколько вероятно, что вы порекомендуете нас другу?» даёт сильный сигнал о здоровье бизнеса: высокий NPS ≈ низкий churn и сильный word-of-mouth, низкий NPS — предвестник оттока.
Аналитику регулярно приходят запросы: «какой у нас NPS?», «упал ли он после релиза?», «отличается ли у premium-сегмента от free?». Обычный exporter в BI-инструменте не всегда даёт эту гибкость — нужен SQL, который можно переиспользовать в дашборде, alert, автоматических отчётах.
В этой статье — готовые SQL-запросы, которые можно сразу вставить в Metabase / Superset / dbt-модель:
- Базовая формула и общий NPS за период
- Динамика по месяцам
- Разрез по сегментам (tier, канал, гео)
- Доверительный интервал
- Связь NPS с retention
Данные в примерах — таблица nps_responses(user_id, score, responded_at).
Формула
NPS определяется по ответам на шкале 0-10:
- Promoters: 9-10
- Passives: 7-8
- Detractors: 0-6
NPS = % Promoters − % DetractorsЗначение от -100 до +100.
1. Общий NPS
WITH counts AS (
SELECT
COUNT(*) FILTER (WHERE score BETWEEN 9 AND 10) AS promoters,
COUNT(*) FILTER (WHERE score BETWEEN 0 AND 6) AS detractors,
COUNT(*) AS total
FROM nps_responses
)
SELECT
(100.0 * promoters / total) - (100.0 * detractors / total) AS nps
FROM counts;Или компактнее:
SELECT
100.0 * (
SUM(CASE WHEN score >= 9 THEN 1 ELSE 0 END) -
SUM(CASE WHEN score <= 6 THEN 1 ELSE 0 END)
) / COUNT(*) AS nps
FROM nps_responses;2. NPS по месяцам
SELECT
DATE_TRUNC('month', responded_at) AS month,
100.0 * (
SUM(CASE WHEN score >= 9 THEN 1 ELSE 0 END) -
SUM(CASE WHEN score <= 6 THEN 1 ELSE 0 END)
) / COUNT(*) AS nps,
COUNT(*) AS responses
FROM nps_responses
GROUP BY 1
ORDER BY 1;3. NPS по сегментам
SELECT
u.tier,
100.0 * (
SUM(CASE WHEN n.score >= 9 THEN 1 ELSE 0 END) -
SUM(CASE WHEN n.score <= 6 THEN 1 ELSE 0 END)
) / COUNT(*) AS nps,
COUNT(*) AS responses
FROM nps_responses n
JOIN users u ON u.id = n.user_id
GROUP BY u.tier
ORDER BY nps DESC;4. Доверительный интервал NPS
NPS — это разница двух пропорций. ДИ сложный. Упрощённо (биномиальное approx):
WITH stats AS (
SELECT
100.0 * (
SUM(CASE WHEN score >= 9 THEN 1 ELSE 0 END) -
SUM(CASE WHEN score <= 6 THEN 1 ELSE 0 END)
) / COUNT(*) AS nps,
COUNT(*) AS n
FROM nps_responses
WHERE responded_at >= '2026-04-01'
)
SELECT
nps,
nps - 1.96 * 100 * SQRT(0.5 * 0.5 / n) AS ci_lower,
nps + 1.96 * 100 * SQRT(0.5 * 0.5 / n) AS ci_upper
FROM stats;Или через bootstrap (в Python).
5. Процент promoters / passives / detractors
SELECT
100.0 * SUM(CASE WHEN score >= 9 THEN 1 ELSE 0 END) / COUNT(*) AS promoters_pct,
100.0 * SUM(CASE WHEN score BETWEEN 7 AND 8 THEN 1 ELSE 0 END) / COUNT(*) AS passives_pct,
100.0 * SUM(CASE WHEN score <= 6 THEN 1 ELSE 0 END) / COUNT(*) AS detractors_pct
FROM nps_responses;6. Response rate
WITH invites AS (
SELECT COUNT(*) AS sent FROM nps_invites WHERE sent_at >= '2026-04-01'
),
responses AS (
SELECT COUNT(*) AS responded FROM nps_responses WHERE responded_at >= '2026-04-01'
)
SELECT
sent,
responded,
100.0 * responded / sent AS response_rate
FROM invites, responses;7. NPS по cohort
WITH user_cohort AS (
SELECT id, DATE_TRUNC('month', signup_at) AS cohort
FROM users
)
SELECT
uc.cohort,
100.0 * (
SUM(CASE WHEN n.score >= 9 THEN 1 ELSE 0 END) -
SUM(CASE WHEN n.score <= 6 THEN 1 ELSE 0 END)
) / COUNT(*) AS nps
FROM nps_responses n
JOIN user_cohort uc ON uc.id = n.user_id
GROUP BY uc.cohort
ORDER BY uc.cohort;8. Связь NPS с retention
SELECT
CASE
WHEN score >= 9 THEN 'promoter'
WHEN score >= 7 THEN 'passive'
ELSE 'detractor'
END AS nps_segment,
AVG(CASE WHEN u.churned THEN 1.0 ELSE 0 END) AS churn_rate
FROM nps_responses n
JOIN users u ON u.id = n.user_id
GROUP BY 1;Обычно: detractors churn сильно выше, promoters — ниже.
Частые ошибки
- Смешивать шкалы (0-10 vs 1-10 vs 0-5)
- Маленький response rate → sample bias
- Apple MPP и self-selection в ответах
- Игнорировать контекст комментариев
- NPS без динамики (одно число бесполезно)
Связанные темы
FAQ
NPS шкала 0-10 или 1-10?
Стандарт — 0-10.
Сколько respondents нужно?
Минимум 100-200 для стабильного NPS. Идеально 1000+.
NPS или CSAT?
NPS — долгосрочная лояльность. CSAT — удовлетворённость после конкретного взаимодействия.
Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.