Как посчитать CSAT по типам обращений в SQL
Содержание:
Зачем разбивка CSAT
Один общий CSAT 85% ничего не говорит, какие именно категории тикетов разочаровывают клиентов. Разбивка по issue type показывает, где self-service не работает, где агенты слабее, где продукт реально ломается. Insights → roadmap для product team или training.
Базовая разбивка
SELECT
issue_category,
COUNT(*) AS surveys_received,
AVG(csat_score) AS avg_csat,
COUNT(*) FILTER (WHERE csat_score >= 4) * 100.0
/ NULLIF(COUNT(*), 0) AS satisfied_pct
FROM csat_surveys
WHERE survey_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY issue_category
HAVING COUNT(*) >= 30
ORDER BY avg_csat ASC;HAVING COUNT(*) >= 30 отсекает категории с шумным сэмплом.
Worst-performing категории
WITH baseline AS (
SELECT AVG(csat_score) AS overall_csat FROM csat_surveys
WHERE survey_date >= CURRENT_DATE - INTERVAL '30 days'
)
SELECT
s.issue_category,
AVG(s.csat_score) AS category_csat,
b.overall_csat,
AVG(s.csat_score) - b.overall_csat AS gap_vs_overall,
COUNT(*) AS n
FROM csat_surveys s, baseline b
WHERE s.survey_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY s.issue_category, b.overall_csat
HAVING COUNT(*) >= 30
ORDER BY gap_vs_overall ASC
LIMIT 10;Категории с CSAT < baseline на 1+ балл — приоритет для root cause analysis.
По агенту и категории
SELECT
agent_id,
issue_category,
AVG(csat_score) AS avg_csat,
COUNT(*) AS n
FROM csat_surveys
WHERE survey_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY agent_id, issue_category
HAVING COUNT(*) >= 20
ORDER BY agent_id, avg_csat ASC;Агент, у которого все категории кроме одной OK — нужен тренинг по этой одной.
Динамика
SELECT
DATE_TRUNC('week', survey_date)::DATE AS week,
issue_category,
AVG(csat_score) AS avg_csat
FROM csat_surveys
WHERE survey_date >= CURRENT_DATE - INTERVAL '12 weeks'
AND issue_category IN ('billing', 'technical', 'feature_request')
GROUP BY DATE_TRUNC('week', survey_date), issue_category
ORDER BY week, issue_category;Падение CSAT в одной категории на 2-3 недели — signal release-проблемы.
Частые ошибки
Ошибка 1. Усреднять без normalize sample. Если billing — 80% тикетов, его CSAT доминирует в общем. Сегментируйте.
Ошибка 2. Survey selection bias. Только 10-30% юзеров отвечают на survey. Те, кто недоволен — чаще. CSAT systematically lower than reality.
Ошибка 3. Игнорировать low-response категории.
Категории с 5-10 surveys — шум. HAVING COUNT(*) >= 30.
Ошибка 4. Считать только closed tickets. Включайте also abandoned tickets (no resolution → likely low CSAT). Без них bias.
Ошибка 5. CSAT vs NPS confusion. CSAT = satisfaction по конкретному ticket. NPS = overall recommendation. Не путать.
Связанные темы
- Как посчитать CSAT в SQL
- Как посчитать NPS в SQL
- Как посчитать CES в SQL
- Как посчитать first response time в SQL
FAQ
Какой CSAT хороший?
4.2-4.5 / 5 — отличный. 3.8-4.2 — норма. < 3.5 — проблема.
Survey selection bias лечить?
Random sample 100% тикетов. Если selection — sweepstake для всех ответивших.
CSAT через email?
Часто бывает — embedded survey в follow-up email. 5-10% response rate.
Per-agent или per-category?
Оба. Agent — for training, category — for product.
Сколько response rate нормально?
10-25% для email. 30-50% для in-product survey.