Какие клиенты дали падение выручки: SQL-мост двух периодов
Выручка снизилась на 170 тысяч. Общая разница не объясняет, произошло ли падение у постоянных клиентов или из отчёта исчезли крупные покупатели. Сравним два периода на уровне клиента, сохраним клиентов только одной стороны и разложим изменение на понятные денежные вклады.
Сделайте периоды сопоставимыми
В примере сравниваются два завершённых месяца с одинаковыми правилами учёта выручки. Суммы заданы в тысячах рублей, а периоды обозначены before и after. В рабочем запросе их задают календарными границами. Если сравнить полный месяц с несколькими днями нового, разница будет отражать и неполное наблюдение.
Сначала агрегируйте продажи до клиента и периода. Отмены, возвраты и валюта должны обрабатываться одинаково. ID клиента должен сохранять идентичность между периодами: смена технического номера после миграции может выглядеть как уход одного клиента и появление другого.
Соберите объединённый список клиентов
INNER JOIN потеряет тех, кто покупал только в одном периоде. Вместо этого создадим список ID через UNION и присоединим к нему обе агрегированные таблицы. Получится одна строка на клиента с прошлой и новой выручкой.
Присутствие клиента определяем по наличию строки периода, а не по ненулевой выручке. Клиент с продажей и возвратом может иметь итог ноль, оставаясь участником периода. COALESCE применяется к денежной сумме уже после сохранения признака присутствия.
WITH sales(client,period,amount) AS (
VALUES ('A','before',100),('B','before',200),('D','before',50),
('A','after',60),('C','after',90),('D','after',30)
), old AS (
SELECT client,SUM(amount) AS revenue FROM sales WHERE period='before' GROUP BY client
), new AS (
SELECT client,SUM(amount) AS revenue FROM sales WHERE period='after' GROUP BY client
), clients AS (
SELECT client FROM old UNION SELECT client FROM new
)
SELECT c.client,
CASE WHEN o.client IS NULL THEN 'entered' WHEN n.client IS NULL THEN 'left' ELSE 'existing' END AS segment,
COALESCE(o.revenue,0) AS before_revenue,COALESCE(n.revenue,0) AS after_revenue,
COALESCE(n.revenue,0)-COALESCE(o.revenue,0) AS delta
FROM clients c LEFT JOIN old o ON o.client=c.client LEFT JOIN new n ON n.client=c.client
ORDER BY delta,c.client;
Назовите группы точно
existing означает, что клиент присутствовал в обоих периодах. left — только в первом, entered — только во втором. entered не доказывает, что это первая покупка за всю историю: для такого вывода нужно проверить более ранние данные. left не означает окончательный уход, а только отсутствие покупок во втором выбранном периоде.
В учебном результате B даёт вклад −200, A — −40, D — −20, C — +90. Сумма вкладов равна −170. Порядок по delta показывает, с каких клиентов начать разбор падения.
Проверьте денежный мост
Сумма прошлой выручки составляет 350, новой — 180. Разница −170 должна совпасть с суммой delta по всем строкам. Если не совпала, проверьте потерянные ключи, повторную агрегацию и фильтры. Это сильнее проверки одного общего итога: у каждой части изменения есть клиент.
Дальше сгруппируйте вклады по статусу. Постоянные клиенты дали −60, отсутствующие во втором периоде −200, появившиеся +90. Для принятия решения откройте конкретные заказы крупных вкладчиков: одно сезонное приобретение может объяснить заметную часть колебания.
Разница выручки сама не объясняет причину. Для постоянных клиентов можно отдельно разложить изменение на число заказов и средний заказ, для отсутствующих — посмотреть обычную частоту покупок и договорные циклы. Не называйте всю отрицательную группу потерянной базой без дополнительного наблюдения.
Для регулярной витрины сохраните границы сравнения и историю пересчётов. Поздний возврат может изменить прошлый месяц, и мост должен воспроизводиться на согласованном срезе. Тогда руководитель получает проверяемое объяснение изменения, а аналитик — список клиентов для следующего исследования.
От запроса к рабочей витрине
В платном курсе вы будете соединять несколько источников, сверять отчёты и рассчитывать клиентские показатели. Автоматическая проверка включает неполные данные и пустые выборки. Эти навыки помогают сохранить клиентов обеих сторон сравнения и довести объяснение изменения выручки до проверяемой витрины.
Откройте программу платного курса «Продвинутый SQL: сложные запросы и задачи для собеседований».
Продолжить разбор: Как сверить два SQL-отчёта: одинаковые суммы могут скрывать ошибки.
Продолжить на практике
- Продвинутый SQL: сложные запросы и задачи для собеседований ↗
Продолжение базового SQL: сложные JOIN, оконные рамки, временные ряды, retention, воронки и рекурсивные CTE. Разбирайте примеры и пишите запросы с автоматической проверкой — от отдельных расчётов до витрины интернет-магазина.
