ABC и XYZ-анализ: что это, как сделать и пример расчёта
ABC-анализ делит клиентов или товары на группы по вкладу в выручку, XYZ — по стабильности продаж. Как сделать оба, матрица из 9 ячеек и пример на SQL.
Содержание статьи
Коммерческий директор просит к пятнице список «главных клиентов», на которых держится выручка, и отдельно — тех, чьи заказы невозможно предсказать. Первый вопрос решает ABC-анализ, второй — XYZ. ABC-анализ — это способ разделить товары, клиентов или сегменты на три группы по вкладу в выручку: A даёт первые 80% денег, B — следующие 15%, C — оставшиеся 5%. XYZ-анализ добавляет второе измерение: насколько ровно объект продаётся от периода к периоду, по коэффициенту вариации. Вместе они дают матрицу из девяти ячеек со своими правилами для каждой.
Коротко
Оба метода — сортировка с порогами, а не статистическая модель. Их ценность в том, что после них понятно, куда смотреть в первую очередь.
- ABC отвечает на вопрос «кто приносит деньги»: объекты сортируют по выручке и режут по накопленной доле.
- XYZ отвечает на вопрос «насколько это предсказуемо»: для каждого объекта считают коэффициент вариации продаж по неделям или месяцам.
- Пороги 80/15/5 и 10/25% — договорённость, а не закон. Их фиксируют до расчёта и пишут в отчёте.
- На учебной базе 64,6% клиентов дают 80% выручки. Правило «20% клиентов — 80% денег» здесь не выполняется, и это нормально.
- Результат анализа — политика: кому персональный менеджер, какой запас держать, где не строить прогноз.
Что такое ABC-анализ простыми словами
В основе — принцип Парето: небольшая часть объектов обычно даёт большую часть результата. ABC превращает это наблюдение в процедуру. Берёте список товаров или клиентов, сортируете по выручке от большей к меньшей, считаете для каждой строки накопленную долю и режете список там, где она пересекает 80% и 95%.
Пороги 80/15/5 — самые распространённые, но не единственные: встречаются 70/20/10 и 50/30/20. Выбор зависит от того, сколько объектов команда готова вести вручную. Если в группу A попало 600 клиентов, а персональный менеджер один, порог стоит сдвинуть.
Мерить можно не только выручкой. Для закупок — оборотом, для склада — числом отгрузок, для прибыли — маржой. От выбора меры результат меняется сильно, об этом в разделе про ошибки.
накопленная доля(i) = Σ выручки объектов с 1 по i ÷ общая выручка; A — до 80%, B — от 80 до 95%, C — выше 95%Объекты отсортированы по выручке по убыванию. Граница включается в A или в B — решите заранее и не меняйте.
Как сделать ABC-анализ: пошагово
Порядок одинаковый для Excel, SQL и BI-инструмента.
- Выберите объект: клиент, товар, категория, сегмент. Один объект — одна строка.
- Выберите меру и период: выручка за квартал, маржа за год. Период должен быть одинаковым для всех объектов.
- Отсортируйте по мере от большей к меньшей и посчитайте долю каждой строки в итоге.
- Посчитайте накопленную долю сверху вниз.
- Присвойте класс по порогам и посчитайте, сколько объектов и сколько денег в каждом классе.
- Проверьте результат глазами: кто оказался на границе A и B и не решает ли всё порядок сортировки одинаковых значений.
Пример ABC-анализа в SQL: клиенты по сумме оплат
Возьмём учебную базу SQL-курса: это подписочный сервис, у которого 912 платящих клиентов оплатили $30 639 с 6 июня по 30 августа. Накопленная доля — оконная функция sum() over (order by …) с рамкой от начала до текущей строки. В сортировку добавлен user_id, чтобы при равной выручке порядок был воспроизводимым.
| Класс | Клиентов | Доля клиентов | Выручка | Доля выручки | Сумма на клиента |
|---|---|---|---|---|---|
| A | 589 | 64,6% | $24 502 | 80,0% | $19–117 |
| B | 242 | 26,5% | $4598 | 15,0% | $19 |
| C | 81 | 8,9% | $1539 | 5,0% | $19 |
with per_client as (
select user_id, sum(amount) as revenue
from payments
group by user_id
),
ranked as (
select
user_id,
revenue,
sum(revenue) over (order by revenue desc, user_id
rows between unbounded preceding and current row)
/ sum(revenue) over () as cum_share
from per_client
),
classified as (
select *,
case when cum_share <= 0.80 then 'A'
when cum_share <= 0.95 then 'B'
else 'C' end as abc
from ranked
)
select
abc,
count(*) as clients,
round(100.0 * count(*) / sum(count(*)) over (), 1) as clients_pct,
sum(revenue) as revenue,
round(100.0 * sum(revenue) / sum(sum(revenue)) over (), 1) as revenue_pct,
min(revenue) as min_revenue,
max(revenue) as max_revenue
from classified
group by abc
order by abc;Почему здесь не 80/20
Две трети клиентов попали в A. Топ-20% клиентов, 182 человека, дают 37,0% выручки, а не 80%. Причина в модели бизнеса: подписка стоит $19, $29 или $39, клиент платит от одного до трёх раз, и различных сумм на клиента всего девять — от $19 до $117. Когда суммы так похожи, выручка распределена ровно, и Парето не срабатывает.
Второе наблюдение важнее. Классы B и C целиком состоят из клиентов с суммой $19, и ещё 26 таких же клиентов попали в A. Всего 349 клиентов заплатили ровно $19, и в какой класс попал каждый, решил user_id в сортировке, то есть случай. В такой ситуации честнее считать ABC по тарифу или числу оплат, а не делать вид, что граница между A и C что-то значит.
Если различных значений меры мало, посмотрите распределение до классов: select revenue, count(*) from … group by revenue. Если большая группа одинаковых значений пересекает порог, классы на ней ничего не различают.
Что такое XYZ-анализ
XYZ оценивает стабильность: насколько сильно продажи объекта скачут от периода к периоду. Мера — коэффициент вариации, стандартное отклонение, делённое на среднее. Он безразмерный, поэтому товар за 100 ₽ и за 10 000 ₽ можно сравнивать напрямую.
Классические пороги из розницы: X — до 10%, Y — от 10 до 25%, Z — больше 25%. Это тоже договорённость. Для ежедневных продаж продуктового магазина она работает, для недельной выручки небольшого B2B-сегмента почти всё окажется в Z.
Периодов нужно хотя бы шесть-восемь, иначе стандартное отклонение считается по двум-трём точкам и ничего не значит. Периоды без продаж обязательно входят в расчёт как нули: если их потерять, нестабильный товар будет выглядеть стабильным.
CV = σ ÷ x̄ × 100%; X — CV ≤ 10%, Y — 10–25%, Z — больше 25%σ — стандартное отклонение продаж по периодам, x̄ — средние продажи за период. Пороги условные, их выбирают под свои данные до расчёта.
Пример XYZ-анализа на SQL: сегменты «страна × тариф»
Клиенты учебной базы для XYZ не годятся: у клиента максимум три оплаты за 12 недель, почти все недели нулевые. Поэтому объект другой — сегмент «страна × тариф», их 12 (55 пользователей без страны исключены). Период — 8 полных недель с 6 июля по 30 августа, за них сегменты принесли $25 299. ABC считаем по тем же 8 неделям, чтобы оба измерения описывали один период.
Здесь есть ловушка. Выручка всей базы растёт: $2098 в неделю, начавшуюся 6 июля, и $4286 в неделю с 24 августа. Рост сам по себе раздувает стандартное отклонение, и сегмент, который ровно растёт, получает высокий CV. Чтобы отделить нестабильность от общего роста, считаем ещё CV доли сегмента в недельной выручке. Класс XYZ ставим по нему, а сырой CV показываем рядом.
| Сегмент | Выручка | Накопл. доля | ABC | CV выручки | CV доли | XYZ |
|---|---|---|---|---|---|---|
| RU · pro | $6206 | 24,5% | A | 24% | 7% | X |
| RU · basic | $5624 | 46,8% | A | 27% | 13% | Y |
| KZ · basic | $2736 | 57,6% | A | 38% | 28% | Z |
| RU · team | $2691 | 68,2% | A | 35% | 25,3% | Z |
| KZ · pro | $1885 | 75,7% | A | 30% | 29% | Z |
| AM · basic | $1368 | 81,1% | B | 42% | 37% | Z |
| BY · basic | $1159 | 85,7% | B | 31% | 27% | Z |
| AM · pro | $986 | 89,5% | B | 50% | 48% | Z |
| BY · pro | $928 | 93,2% | B | 50% | 49% | Z |
| KZ · team | $858 | 96,6% | C | 70% | 65% | Z |
| AM · team | $546 | 98,8% | C | 69% | 68% | Z |
| BY · team | $312 | 100% | C | 100% | 97% | Z |
with weekly as (
select u.country || ' · ' || p.plan as segment,
date_trunc('week', p.paid_at) as week,
sum(p.amount) as revenue
from payments p
join users u using (user_id)
where p.paid_at between date '2026-07-06' and date '2026-08-30'
and u.country <> ''
group by all
),
grid as ( -- неделя без оплат должна дать 0, а не пропасть
select s.segment, w.week, coalesce(x.revenue, 0) as revenue
from (select distinct segment from weekly) s
cross join (select distinct week from weekly) w
left join weekly x on x.segment = s.segment and x.week = w.week
),
with_share as (
select *, revenue / sum(revenue) over (partition by week) as week_share
from grid
),
per_segment as (
select segment,
sum(revenue) as revenue,
stddev_pop(revenue) / avg(revenue) as cv_revenue,
stddev_pop(week_share) / avg(week_share) as cv_share
from with_share
group by segment
),
abc as (
select *,
sum(revenue) over (order by revenue desc
rows between unbounded preceding and current row)
/ sum(revenue) over () as cum_share
from per_segment
)
select segment, revenue,
round(100 * cum_share, 1) as cum_pct,
case when cum_share <= 0.80 then 'A'
when cum_share <= 0.95 then 'B' else 'C' end as abc,
round(100 * cv_revenue) as cv_revenue_pct,
round(100 * cv_share) as cv_share_pct,
case when cv_share <= 0.10 then 'X'
when cv_share <= 0.25 then 'Y' else 'Z' end as xyz
from abc
order by revenue desc;У RU · team CV доли 25,3% — на треть процентного пункта выше порога, поэтому класс Z. Такие пограничные случаи пометьте в отчёте, а не делайте вид, что между 25,0% и 25,3% есть разница. По сырому CV в Y попал бы только RU · pro, все остальные — в Z: рост базы сделал бы классификацию бессмысленной.
Матрица ABC-XYZ: что делать в каждой ячейке
Два класса дают девять комбинаций. Для товаров матрица обычно определяет политику запасов, для клиентов — уровень внимания и формат работы. Ниже общая схема; конкретные действия зависят от бизнеса.
| Ячейка | Что это | Что делать |
|---|---|---|
| AX | много денег, продаётся ровно | не допускать дефицита, прогнозировать автоматически, беречь от рискованных экспериментов |
| AY | много денег, умеренные колебания | страховой запас, разобрать причины колебаний: сезон, акции |
| AZ | много денег, непредсказуемо | персональная работа, заказ под клиента, выяснить, откуда скачки |
| BX | средний вклад, стабильно | автоматизировать закупку или обслуживание, минимум ручного труда |
| BY | средний вклад, колеблется | стандартные правила, пересмотр раз в квартал |
| BZ | средний вклад, хаотично | работать под заказ, не держать большой запас |
| CX | мало денег, стабильно | автопополнение, минимальное внимание |
| CY | мало денег, колеблется | сократить ассортимент или перевести на заказ |
| CZ | мало денег, хаотично | кандидаты на вывод или на работу только под заказ |
- На учебной базе: AX — 1 сегмент (RU · pro), AY — 1 (RU · basic), AZ — 3 (KZ · basic, RU · team, KZ · pro), BZ — 4, CZ — 3. Ячейки BX, BY, CX и CY пустые.
- Практический вывод для команды: плановые показатели выручки имеет смысл ставить на RU · pro и RU · basic, остальное прогнозировать суммой по стране или тарифу.
- Тариф team в Казахстане, Армении и Беларуси — CZ: в отдельные недели по нему нет ни одной оплаты. Строить по нему недельный дашборд — значит каждую неделю обсуждать шум.
Как сделать ABC-анализ в Excel
Отсортируйте таблицу по выручке по убыванию. В соседнем столбце посчитайте долю строки =B2/СУММ($B$2:$B$913), в следующем — накопленную долю =СУММ($C$2:C2). Класс ставит формула =ЕСЛИ(D2<=0,8;"A";ЕСЛИ(D2<=0,95;"B";"C")). Для XYZ разложите продажи по периодам в столбцы, заполните пустые ячейки нулями и посчитайте =СТАНДОТКЛОН.Г(E2:L2)/СРЗНАЧ(E2:L2). Итог по классам — сводная таблица. Excel удобен для разового анализа; если его нужно пересчитывать каждый месяц, SQL-запрос или BI-отчёт избавят от ручной сортировки и потерянных строк.
Частые ошибки в ABC и XYZ-анализе
Большинство ошибок связано не с формулой, а с тем, что именно попало в расчёт.
- Выручка вместо маржи. Товар из группы A по выручке может продаваться со скидкой в ноль. Для решений об ассортименте считайте ABC по валовой прибыли или делайте оба варианта и сравнивайте.
- Короткая история. XYZ по трём месяцам — это стандартное отклонение по трём точкам. Нужно минимум шесть-восемь периодов одинаковой длины.
- Новые клиенты и товары. Кто появился месяц назад, попадёт в C и в Z просто потому, что у него мало периодов. Считайте их отдельно или только за полные периоды жизни.
- Сезонность. Новогодние игрушки всегда будут Z по месяцам, хотя их спрос предсказуем. Для сезонных товаров сравнивайте год к году или убирайте сезонную составляющую.
- Общий рост. Если растёт весь бизнес, CV растёт у всех. Считайте CV доли в итоге или от отклонений от тренда, как в примере выше.
- Потерянные нули. Периоды без продаж должны войти в расчёт как 0. В SQL для этого нужна сетка «объект × период» и
left join. - Одинаковые значения на границе. Если сотни объектов имеют одну сумму, класс решает порядок сортировки. Проверьте распределение до того, как отдавать классы менеджерам.
Что читать дальше
ABC смотрит только на деньги. Если нужно учесть ещё и давность и частоту покупок, следующий шаг — RFM-анализ. Потренироваться на тех же данных можно в песочнице: посчитайте ABC клиентов по числу оплат вместо суммы и сравните, сколько человек поменяли класс.
Материалы по теме

RFM-анализ: что это, как посчитать в SQL и что делать с сегментами
RFM-анализ делит клиентов по давности, частоте и сумме покупок. Как посчитать баллы в SQL, назвать сегменты и что делать, если бизнес работает по подписке.

Сегментация пользователей: что это, как делить и где она обманывает
Сегментация — деление пользователей на группы по признаку, чтобы увидеть различия, которые прячет среднее. Виды сегментов, отличие сегмента от когорты, RFM-анализ в SQL, маленькие сегменты, смена состава и сегменты в A/B-тестах — на учебной базе.

CPO: что это, формула и чем отличается от CPA и CAC
CPO — стоимость одного заказа: маркетинговые расходы, делённые на число заказов. Формула, пример расчёта, отличие от CPA и CAC и безубыточный CPO.