Почему заказы растут, а выручка падает: заказы × средний чек
Содержание курса
Почему выручка может падать при росте числа заказов
Посмотрим, как рост заказов может сопровождаться падением общей выручки. Для разбора используем учебную таблицу demo_orders, состоящую из 9 записей:
order_id,order_date,status,gross_revenue D01,2024-03-04,paid,4500 D02,2024-03-16,paid,3000 D03,2024-03-28,paid,1500 D04,2024-03-29,cancelled,12000 D05,2024-04-03,paid,1000 D06,2024-04-11,paid,1200 D07,2024-04-19,paid,2000 D08,2024-04-26,paid,3000 D09,2024-04-29,pending,8000
Соберем помесячную агрегацию оплаченных заказов за март и апрель 2024 года.
Вариант на SQL
DROP TABLE IF EXISTS demo_orders;
CREATE TABLE demo_orders (
order_id TEXT PRIMARY KEY,
order_date TEXT NOT NULL,
status TEXT NOT NULL,
gross_revenue INTEGER NOT NULL
);
INSERT INTO demo_orders VALUES
('D01', '2024-03-04', 'paid', 4500),
('D02', '2024-03-16', 'paid', 3000),
('D03', '2024-03-28', 'paid', 1500),
('D04', '2024-03-29', 'cancelled', 12000),
('D05', '2024-04-03', 'paid', 1000),
('D06', '2024-04-11', 'paid', 1200),
('D07', '2024-04-19', 'paid', 2000),
('D08', '2024-04-26', 'paid', 3000),
('D09', '2024-04-29', 'pending', 8000);
SELECT strftime('%Y-%m', order_date) AS month,
COUNT(*) AS paid_orders,
SUM(gross_revenue) AS gross_revenue,
1.0 * SUM(gross_revenue) / COUNT(*) AS aov
FROM demo_orders
WHERE status = 'paid'
AND order_date >= '2024-03-01'
AND order_date < '2024-05-01'
GROUP BY strftime('%Y-%m', order_date)
ORDER BY month;
Результат выполнения запроса:
| month | paid_orders | gross_revenue | aov |
|---|---|---|---|
| 2024-03 | 3 | 9000 | 3000.0 |
| 2024-04 | 4 | 7200 | 1800.0 |
Вариант на pandas
import pandas as pd
from io import StringIO
demo_csv = """
order_id,order_date,status,gross_revenue
D01,2024-03-04,paid,4500
D02,2024-03-16,paid,3000
D03,2024-03-28,paid,1500
D04,2024-03-29,cancelled,12000
D05,2024-04-03,paid,1000
D06,2024-04-11,paid,1200
D07,2024-04-19,paid,2000
D08,2024-04-26,paid,3000
D09,2024-04-29,pending,8000
"""
demo_orders = pd.read_csv(StringIO(demo_csv))
paid = demo_orders.loc[
demo_orders["status"].eq("paid")
& demo_orders["order_date"].ge("2024-03-01")
& demo_orders["order_date"].lt("2024-05-01")
].copy()
paid["month"] = paid["order_date"].str.slice(0, 7)
monthly = paid.groupby("month", as_index=False).agg(
paid_orders=("order_id", "size"),
gross_revenue=("gross_revenue", "sum"),
)
monthly["aov"] = monthly["gross_revenue"] / monthly["paid_orders"]
print(monthly.to_string(index=False))
Вывод программы:
month paid_orders gross_revenue aov 2024-03 3 9000 3000.0 2024-04 4 7200 1800.0
Обратите внимание на строки D04 (cancelled) и D09 (pending): фильтр исключил их из расчета, они не попали ни в , ни в . В SQL умножение на 1.0 принудительно переводит деление в вещественное, исключая целочисленное усечение.
Сравним два месяца: в марте было заказа с выручкой руб. (), а в апреле — заказа с выручкой руб. (). Число заказов выросло на треть (с 3 до 4), однако выручка упала на рублей. Причина — резкое падение среднего чека с до рублей.
Если бы средний чек в апреле остался на уровне марта ( руб.), то при тех же 4 заказах выручка составила бы рублей. Этот контрастный сценарий наглядно доказывает: опираясь исключительно на число заказов , невозможно определить направление движения выручки .
