Как посчитать Marketing ROI в SQL
payments(amount), в части строк amount равно NULL. Какой запрос посчитает количество всех строк в таблице, включая строки с NULL в столбце amount?Содержание:
Зачем Marketing ROI
ROAS показывает выручку на рубль рекламного бюджета. Marketing ROI идёт дальше — учитывает все маркетинговые затраты (креативы, агентство, а не только медиабюджет) и маржу. ROI 50% означает: на $1 вложений — прибыль $1.50.
Формула
Marketing ROI = (Revenue Generated × Gross Margin - Marketing Cost) / Marketing Cost × 100%
ROMI (Return on Marketing Investment) = (Marketing Profit - Marketing Cost) / Marketing CostБазовый расчёт
WITH attribution AS (
SELECT
channel,
SUM(amount) AS attributed_revenue
FROM conversions
GROUP BY channel
),
spend AS (
SELECT
channel,
SUM(spend) AS total_spend
FROM marketing_spend
WHERE month >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY channel
)
SELECT
a.channel,
a.attributed_revenue,
s.total_spend,
(a.attributed_revenue - s.total_spend) / NULLIF(s.total_spend, 0) * 100 AS roas_minus_one_pct,
(a.attributed_revenue * 0.4 - s.total_spend) / NULLIF(s.total_spend, 0) * 100 AS marketing_roi_with_margin
FROM attribution a
JOIN spend s ON s.channel = a.channel
ORDER BY marketing_roi_with_margin DESC;0.4 — заложенная gross margin.
ROMI vs ROAS
| Метрика | Формула | Учитывает маржу |
|---|---|---|
| ROAS | revenue / ad spend | Нет |
| ROMI | (revenue × margin - cost) / cost | Да |
ROAS 4.0 при марже 20% → ROMI = (4 × 0.2 - 1) / 1 = -20%. Технически это убыток.
Time-to-payback
Когда маркетинговые вложения окупаются:
WITH customer_cohort AS (
SELECT
u.user_id,
u.acquired_at,
u.acquisition_cost
FROM users u
WHERE u.acquired_at >= CURRENT_DATE - INTERVAL '12 months'
),
cumulative_revenue AS (
SELECT
c.user_id,
c.acquired_at,
c.acquisition_cost,
EXTRACT(EPOCH FROM (o.created_at - c.acquired_at)) / 86400 AS days_after_acq,
SUM(o.total) OVER (
PARTITION BY c.user_id ORDER BY o.created_at
) AS cum_revenue
FROM customer_cohort c
JOIN orders o ON o.user_id = c.user_id
WHERE o.status = 'paid'
)
SELECT
user_id,
acquisition_cost,
MIN(days_after_acq) FILTER (WHERE cum_revenue * 0.4 >= acquisition_cost) AS days_to_payback
FROM cumulative_revenue
GROUP BY user_id, acquisition_cost;× 0.4 — маржа. Окупаемость наступает, когда накопленная прибыль ≥ стоимости привлечения.
Частые ошибки
Ошибка 1. Путать ROAS с ROI. ROAS не учитывает маржу, а ROI — учитывает.
Ошибка 2. Маркетинговые затраты ≠ рекламный бюджет. К бюджету добавьте комиссии агентства, производство контента и зарплаты маркетинговой команды — это и есть реальные затраты на маркетинг.
Ошибка 3. Окна атрибуции. ROI зависит от модели атрибуции: разные модели дают разные цифры ROI.
Ошибка 4. Бренд-маркетинг. У бренд-кампаний эффект отложенный, поэтому ROI на коротком окне их занижает.
Ошибка 5. Игнорировать halo-эффект. Маркетинг привёл пользователя, который рассказал другу, — это тоже выручка от кампании, но её сложно атрибутировать.
Связанные темы
- Как посчитать ROAS в SQL
- Как посчитать CAC в SQL
- Как посчитать LTV в SQL
- Как посчитать CAC Payback в SQL
FAQ
Какой Marketing ROI ok?
Ориентир такой: 100% и выше — отлично, 30–50% — рабочая норма. Отрицательный ROI не всегда провал — иногда это осознанные вложения в будущее или в бренд.
ROI положительный, но < 100% — что значит?
Каждый вложенный доллар приносит от 1 до 2 долларов прибыли. Это уже прибыльно, но вы находитесь между точкой безубыточности и по-настоящему высокой отдачей.
ROAS 5, but ROI -10% — почему?
Из-за низкой маржи. При марже 20% выручка $5 даёт всего $1 прибыли, а расходы — тоже $1, так что ROI выходит около нуля. Высокий ROAS ничего не гарантирует, если маржа маленькая.
Multi-touch ROI?
Считайте по multi-touch атрибуции: распределяете выручку между каналами по выбранной модели, а затем применяете формулу с маржой к каждому каналу.
Brand marketing ROI?
У бренд-маркетинга длинный горизонт отдачи, поэтому по обычному ROI его почти не оценить. Смотрят на исследования узнаваемости бренда в связке с анализом LTV.