Как посчитать Return Rate в SQL
HAVING в SQL-запросе с группировкой?Содержание:
Зачем Return Rate
Return Rate — доля возвращённых заказов или товаров. Высокий return rate сигналит о проблемах с UX: неверные размерные сетки, плохо описанный товар, фото вводит в заблуждение. И это прямой удар по марже — логистика и обработка возврата стоят денег.
Формула
Return Rate (orders) = returned_orders / total_orders × 100%
Return Rate (items) = returned_items / total_items × 100%
Return Rate (value) = return_value / order_value × 100%Базовый расчёт
SELECT
DATE_TRUNC('month', order_date) AS month,
COUNT(DISTINCT order_id) AS total_orders,
COUNT(DISTINCT order_id) FILTER (WHERE returned = TRUE) AS returned_orders,
COUNT(DISTINCT order_id) FILTER (WHERE returned = TRUE)::NUMERIC * 100
/ COUNT(DISTINCT order_id) AS return_rate_pct,
SUM(order_value) AS total_value,
SUM(return_value) AS returned_value,
SUM(return_value) * 100.0 / SUM(order_value) AS return_value_pct
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY 1
ORDER BY 1;По категориям
SELECT
p.category,
COUNT(*) AS items_ordered,
COUNT(*) FILTER (WHERE oi.returned) AS items_returned,
COUNT(*) FILTER (WHERE oi.returned)::NUMERIC * 100 / COUNT(*) AS return_rate_pct,
SUM(oi.amount) AS revenue,
SUM(oi.amount) FILTER (WHERE oi.returned) AS returned_revenue
FROM order_items oi
JOIN products p ON p.product_id = oi.product_id
WHERE oi.ordered_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY p.category
HAVING COUNT(*) >= 100
ORDER BY return_rate_pct DESC;Одежда — обычно 20–30%. Электроника — 10–15%. Книги — 5–10%.
Причины возвратов
SELECT
return_reason,
COUNT(*) AS returns,
COUNT(*)::NUMERIC * 100 / SUM(COUNT(*)) OVER () AS share_pct,
AVG(time_to_return_days) AS avg_days_to_return
FROM returns
WHERE returned_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY return_reason
ORDER BY returns DESC;Топ-причины подсказывают, что чинить:
- Не подошёл размер → размерные сетки и рекомендации
- Повреждён → ревизия упаковки
- Не соответствует описанию → фото и текст карточки
- Качество → проверка поставщика
Окно возврата (когда возврат засчитан)
Окно возврата 30 дней против 90 дней:
SELECT
order_date,
-- 30-day return rate
COUNT(*) FILTER (WHERE returned_at <= order_date + INTERVAL '30 days') AS returned_30d,
-- 90-day return rate
COUNT(*) FILTER (WHERE returned_at <= order_date + INTERVAL '90 days') AS returned_90d,
COUNT(*) AS total
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY order_date
ORDER BY order_date;По когорте клиентов
WITH first_order AS (
SELECT user_id, MIN(order_date) AS first_order_date
FROM orders
GROUP BY user_id
)
SELECT
DATE_TRUNC('month', f.first_order_date) AS cohort,
COUNT(o.order_id) AS orders,
COUNT(o.order_id) FILTER (WHERE o.returned) AS returns,
COUNT(o.order_id) FILTER (WHERE o.returned)::NUMERIC * 100 / COUNT(o.order_id) AS return_rate_pct
FROM orders o
JOIN first_order f USING (user_id)
WHERE o.order_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY 1
ORDER BY 1;Частые ошибки
Ошибка 1. Возврат денег vs возврат товара. Refund (вернули деньги) ≠ return (товар физически приехал назад). Это разные метрики, и мерить их надо отдельно.
Ошибка 2. Запаздывание. Возвраты отстают от заказов по времени. Return rate текущего месяца занижен — часть возвратов ещё не оформлена.
Ошибка 3. Частичные возвраты. В заказе 5 товаров, вернули один. Считать по заказам или по товарам? Определитесь заранее.
Ошибка 4. Обмен как возврат. Считать ли обмен возвратом? Зависит от бизнеса — это вопрос договорённости.
Ошибка 5. Мошеннические возвраты. Вардробинг: купил, поносил, вернул. Ловится по клиентам, которые возвращают слишком часто.
Связанные темы
- Как посчитать fill rate в SQL
- Как посчитать perfect order rate в SQL
- Как посчитать gross margin в SQL
- Как посчитать CSAT в SQL
FAQ
Какой return rate нормальный?
Сильно зависит от категории: у одежды это 20–30%, у электроники 10–15%, у книг меньше 5%. Единого «хорошего» значения нет — сравнивайте каждую категорию с её же бенчмарком, а не общий показатель по магазину.
Return rate растёт — что делать?
Раскладывайте показатель на срезы: по категории, по причине возврата, по конкретному SKU. Обычно рост тянут несколько позиций — найдите топ SKU по возвратам и чините у них размерную сетку, фото или качество.
Какое окно возврата брать?
Отраслевой стандарт — 30 дней, более лояльные к клиенту магазины дают 90. Главное — зафиксировать окно в политике и одинаково применять его во всех расчётах, иначе цифры между отчётами не сойдутся.
Как ловить вардробинг?
Считайте return rate в разрезе клиента, а не только товара. Тех, кто возвращает подозрительно часто, помечайте флагом и разбирайте вручную — это и есть кандидаты в вардробинг.
Возврат денег или возврат товара?
Refund — это возврат денег, return — возврат самого товара. Refund без return (деньги вернули, а товар остался у клиента) обычно означает компенсацию за брак или жест доброй воли со стороны поддержки.