Как посчитать GMV в SQL

Закрепи формулу gmv в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать gmv в Telegram

Зачем GMV

Маркетплейс отчитывается: «GMV вырос на 30% за квартал». Аудитория хлопает. Аналитик копает: revenue компании выросла на 5%, take rate упал с 10% до 8%. Реальная картина — рост за счёт скидок и промо, не органический.

GMV — главная top-line метрика маркетплейсов и e-com платформ. Аналитики постоянно строят: GMV по категориям, по селлерам, динамика по неделям, GMV новых vs повторных. В статье — SQL-запросы и разница между GMV / Revenue / Net GMV.

Что такое GMV

GMV (Gross Merchandise Value) — суммарная стоимость товаров и услуг, проданных через платформу за период.

GMV = Σ (item_price × quantity) для всех заказов в статусе оплачен/доставлен

GMV ≠ Revenue. На маркетплейсе GMV — это деньги, которые прошли через платформу, а Revenue — комиссия (take rate × GMV) + дополнительные сервисы.

Базовый расчёт

Данные: orders(order_id, user_id, total, status, created_at).

SELECT
    SUM(total) AS gmv
FROM orders
WHERE status IN ('paid', 'delivered')
  AND created_at >= '2026-04-01'
  AND created_at <  '2026-05-01';

Важно: фильтр по status обязателен. Корзины (pending) и отменённые (cancelled) не считаются в GMV.

GMV по разрезам

По категориям

SELECT
    category,
    SUM(total) AS gmv,
    COUNT(*) AS orders,
    SUM(total)::NUMERIC / NULLIF(COUNT(*), 0) AS aov
FROM orders
WHERE status IN ('paid', 'delivered')
  AND created_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY category
ORDER BY gmv DESC;

По селлерам / мерчантам

SELECT
    seller_id,
    SUM(total) AS gmv,
    COUNT(DISTINCT user_id) AS buyers,
    COUNT(*) AS orders
FROM orders
WHERE status IN ('paid', 'delivered')
  AND created_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY seller_id
ORDER BY gmv DESC
LIMIT 100;

Новые vs повторные покупатели

WITH user_orders AS (
    SELECT
        user_id,
        total,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at) AS order_num
    FROM orders
    WHERE status IN ('paid', 'delivered')
)
SELECT
    CASE WHEN order_num = 1 THEN 'new' ELSE 'repeat' END AS buyer_type,
    SUM(total) AS gmv,
    COUNT(*) AS orders,
    AVG(total) AS aov
FROM user_orders
GROUP BY 1;

Здоровое соотношение: 60-80% GMV из повторных в зрелом маркетплейсе.

Закрепи формулу gmv в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать gmv в Telegram

GMV vs Revenue vs Net GMV

Метрика Что считаем Формула
GMV Полная стоимость заказов SUM(total) для всех оплаченных
Net GMV GMV минус возвраты, отмены, скидки от платформы SUM(total) - SUM(refunds) - SUM(platform_discounts)
Revenue Заработок платформы SUM(commission) + SUM(ads_revenue) + ...
WITH gross AS (
    SELECT SUM(total) AS gmv
    FROM orders
    WHERE status IN ('paid', 'delivered')
      AND created_at >= '2026-04-01' AND created_at < '2026-05-01'
),
refunds AS (
    SELECT SUM(refund_amount) AS refunded
    FROM order_refunds
    WHERE refund_date >= '2026-04-01' AND refund_date < '2026-05-01'
),
platform_discounts AS (
    SELECT SUM(discount_amount) AS discount
    FROM order_discounts
    WHERE source = 'platform'
      AND created_at >= '2026-04-01' AND created_at < '2026-05-01'
),
revenue AS (
    SELECT SUM(commission_amount) AS commission
    FROM order_commissions
    WHERE commission_date >= '2026-04-01' AND commission_date < '2026-05-01'
)
SELECT
    g.gmv,
    g.gmv - COALESCE(r.refunded, 0) - COALESCE(pd.discount, 0) AS net_gmv,
    rev.commission AS revenue,
    rev.commission::NUMERIC / NULLIF(g.gmv, 0) * 100 AS take_rate_pct
FROM gross g
CROSS JOIN refunds r
CROSS JOIN platform_discounts pd
CROSS JOIN revenue rev;

GMV динамика и сезонность

WITH daily AS (
    SELECT
        DATE_TRUNC('day', created_at) AS day,
        SUM(total) AS gmv
    FROM orders
    WHERE status IN ('paid', 'delivered')
      AND created_at >= CURRENT_DATE - INTERVAL '90 days'
    GROUP BY 1
)
SELECT
    day,
    gmv,
    AVG(gmv) OVER (
        ORDER BY day
        ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
    ) AS gmv_7d_avg,
    gmv * 100.0 / NULLIF(LAG(gmv, 7) OVER (ORDER BY day), 0) - 100 AS wow_change_pct
FROM daily
ORDER BY day;

7-day rolling average сглаживает дневной шум. WoW change — это GMV сегодня vs неделю назад, в процентах.

Частые ошибки

Ошибка 1. Включать pending / cancelled

SUM(total) FROM orders без фильтра status завышает GMV на 20-30%. Только paid / delivered / completed (зависит от воркфлоу).

Ошибка 2. Игнорировать возвраты

В первый месяц GMV кажется высоким, через 30 дней приходит волна refund — реальный GMV ниже. Считайте Net GMV для управленческих решений.

Ошибка 3. GMV в смешанной валюте

Заказы в рублях, тенге, лирах — сложить нельзя без приведения. SUM(amount * fx_rate) с курсом на дату транзакции.

Ошибка 4. Подмена GMV на Revenue в отчёте

«GMV вырос на 30%» — но это revenue (комиссия). Маркетинг радуется, финдиректор спрашивает: «а где GMV?». Договоритесь о терминологии в команде.

Ошибка 5. Дабл-каунт refund

Если refund попадает и в order_refunds, и снижает status заказа на refunded — можно вычесть дважды. Проверьте, что данные не пересекаются.

Ошибка 6. GMV без учёта tax

Иногда total — это GMV с НДС, иногда без. На маркетплейсах часто GMV считают без tax (Net of VAT). Уточните у финансистов формулу.

Связанные темы

FAQ

GMV — это revenue?

Нет. GMV — стоимость заказов через платформу. Revenue — заработок платформы (комиссия + сервисы). На WB take rate ~12-15% → revenue ≈ 12-15% от GMV.

Какая take rate считается хорошей?

Маркетплейсы: 5-15%. Доставка еды (UberEats, Delivery): 20-35%. Билеты на концерты: 5-10%. Travel: 15-25%. Сравнивайте с конкурентами в своей категории.

GMV или Net GMV — что показывать?

Внутренне — обе. PR-релизы обычно про GMV (выглядит больше). Управленческие отчёты — Net GMV (отражает реальный экономический эффект).

GMV считать по дате заказа или дате доставки?

Чаще по дате заказа (когда деньги прошли). Но для логистических метрик — по дате доставки. Зафиксируйте определение в команде.

Как сравнить GMV между маркетплейсами?

Сложно — разные курсы валют, методология (с tax / без), включение цифровых товаров. Используйте опубликованные цифры компаний, не стройте сравнение «на коленке».