Как посчитать HHI в SQL
Содержание:
Зачем HHI
HHI (Herfindahl-Hirschman Index) — мера концентрации. Изначально для антимонопольного анализа: насколько рынок монополизирован. В продуктовой аналитике используют, чтобы понять, не зависит ли бизнес от 2-3 клиентов или единственной географии. Высокий HHI = риск: уход одного клиента обрушит выручку.
Формула
HHI = Σ s_i²где s_i — доля игрока i (от 0 до 1 или от 0 до 100). Диапазон зависит от шкалы:
- доли 0–1: HHI ∈ [1/N, 1]
- доли 0–100 (проценты): HHI ∈ [10000/N, 10000]
Антимонопольная классификация (US DOJ, шкала 0–10000):
- < 1500 — низкая концентрация
- 1500–2500 — умеренная
- > 2500 — высокая
HHI по клиентам
Сколько выручки приносят топ-клиенты в этом году:
WITH customer_share AS (
SELECT
customer_id,
SUM(amount) AS revenue,
SUM(amount) * 100.0 / SUM(SUM(amount)) OVER () AS share_pct
FROM orders
WHERE order_date >= '2026-01-01'
GROUP BY customer_id
)
SELECT
SUM(share_pct * share_pct) AS hhi
FROM customer_share;HHI > 2500 означает, что эквивалентно 4 одинаковым клиентам делят весь доход — концентрация серьёзная.
HHI во времени
Динамика концентрации помесячно:
WITH monthly_shares AS (
SELECT
DATE_TRUNC('month', order_date)::DATE AS month,
customer_id,
SUM(amount) * 100.0
/ SUM(SUM(amount)) OVER (PARTITION BY DATE_TRUNC('month', order_date)) AS share_pct
FROM orders
GROUP BY DATE_TRUNC('month', order_date), customer_id
)
SELECT
month,
SUM(share_pct * share_pct) AS hhi,
COUNT(*) AS active_customers
FROM monthly_shares
GROUP BY month
ORDER BY month;Растущий HHI — выручка концентрируется у меньшего числа клиентов (тревожно для SaaS). Падающий HHI — диверсификация работает.
HHI по сегментам
Концентрация в разрезе географии или плана:
WITH segment_shares AS (
SELECT
u.country,
o.customer_id,
SUM(o.amount) * 100.0
/ SUM(SUM(o.amount)) OVER (PARTITION BY u.country) AS share_pct,
COUNT(*) OVER (PARTITION BY u.country) AS segment_size
FROM orders o
JOIN users u USING (customer_id)
WHERE o.order_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY u.country, o.customer_id
)
SELECT
country,
SUM(share_pct * share_pct) AS hhi,
MAX(segment_size) AS customers_in_country
FROM segment_shares
GROUP BY country
HAVING MAX(segment_size) >= 30
ORDER BY hhi DESC;Маленькие сегменты исключаем (segment_size >= 30) — иначе при 2 клиентах HHI всегда близко к 5000+.
Частые ошибки
Ошибка 1. Смешать шкалы. Если считаете доли в долях (0–1), а интерпретируете по DOJ-шкале (0–10000), получите бессмыслицу. Умножьте на 100 ДО квадрата или используйте один масштаб всюду.
Ошибка 2. HHI для слишком маленьких выборок. 2-3 клиента всегда дадут «концентрированный рынок». Минимум 10–20 игроков для осмысленного HHI.
Ошибка 3. Не нормализовать на total.
Если суммы доли не дают 100%, HHI несравним между периодами. SUM(amount) OVER () — обязательно.
Ошибка 4. HHI без контекста. HHI = 3000 само по себе ничего не говорит. Сравнивайте с прошлым периодом или с конкурентами.
Ошибка 5. Считать HHI по числу клиентов, а не по выручке. По числу — индекс равномерности когорты (что-то вроде Simpson diversity). По выручке — настоящая бизнес-концентрация.
Связанные темы
- Как посчитать Pareto в SQL
- Как посчитать share of wallet в SQL
- Как посчитать customer segments в SQL
- Как посчитать RFM segmentation в SQL
FAQ
Шкала 0–1 или 0–10000?
Антимонопольщики используют 0–10000 (проценты в квадрате). Для внутренних дашбордов удобнее 0–1, чтобы было проще читать.
Какой HHI считается опасным?
Для customer concentration: > 2500 — стоит диверсифицировать. > 4000 — критично, треть выручки на 1–2 клиентах.
HHI vs Gini?
HHI чувствителен к топ-игрокам (квадрат). Gini — общая неравномерность. Для антимонопольного анализа — HHI, для социального — Gini.
Можно ли по продуктам?
Да: концентрация выручки по SKU. Высокий HHI = бизнес на 1 хитовом продукте.
Включать ли churned customers?
В исторических периодах — да (они были частью рынка). В текущем — только активных в этот период.