Как посчитать price elasticity в SQL
Содержание:
Зачем price elasticity
Price elasticity (PE) — насколько падает спрос при росте цены. Если повысили цену на 10%, продажи упали на 15% — эластичность −1.5 (эластично, плохо для revenue). Если упали на 5% — −0.5 (неэластично, повышение даст рост revenue). Базовая метрика pricing-команды.
Формула
PE = (Δquantity / quantity) / (Δprice / price)Или через логарифмы:
PE = ln(Q2 / Q1) / ln(P2 / P1)Логарифмическая версия симметрична: PE(P1→P2) = PE(P2→P1).
Эластичность в SQL
Сравнение двух периодов с разными ценами:
WITH periods AS (
SELECT
product_id,
DATE_TRUNC('month', sold_at)::DATE AS month,
AVG(price) AS avg_price,
COUNT(*) AS quantity
FROM orders
WHERE sold_at >= '2026-01-01'
GROUP BY product_id, DATE_TRUNC('month', sold_at)
),
with_prev AS (
SELECT
product_id,
month,
avg_price,
quantity,
LAG(avg_price) OVER (PARTITION BY product_id ORDER BY month) AS prev_price,
LAG(quantity) OVER (PARTITION BY product_id ORDER BY month) AS prev_quantity
FROM periods
)
SELECT
product_id,
month,
avg_price,
quantity,
LN(quantity::NUMERIC / NULLIF(prev_quantity, 0))
/ NULLIF(LN(avg_price::NUMERIC / NULLIF(prev_price, 0)), 0) AS price_elasticity
FROM with_prev
WHERE prev_price IS NOT NULL
AND ABS(avg_price - prev_price) / NULLIF(prev_price, 0) > 0.01 -- хотя бы 1% изменения
ORDER BY month;ABS(...) > 0.01 отсекает периоды без значимого price change — иначе деление на тончайший знаменатель даст шум.
Эксперимент с ценами
A/B-test разных цен — самый чистый способ:
WITH variants AS (
SELECT
variant,
AVG(price) AS avg_price,
COUNT(*) FILTER (WHERE event = 'purchase') AS purchases,
COUNT(*) FILTER (WHERE event = 'view') AS views,
COUNT(*) FILTER (WHERE event = 'purchase')::NUMERIC
/ NULLIF(COUNT(*) FILTER (WHERE event = 'view'), 0) AS cr
FROM pricing_experiment_events
WHERE experiment_id = 'pricing_2026q2'
GROUP BY variant
)
SELECT
-- Pair A vs B
(SELECT cr FROM variants WHERE variant = 'A') AS cr_a,
(SELECT cr FROM variants WHERE variant = 'B') AS cr_b,
(SELECT avg_price FROM variants WHERE variant = 'A') AS price_a,
(SELECT avg_price FROM variants WHERE variant = 'B') AS price_b,
LN((SELECT cr FROM variants WHERE variant = 'B')
/ NULLIF((SELECT cr FROM variants WHERE variant = 'A'), 0))
/ NULLIF(LN((SELECT avg_price FROM variants WHERE variant = 'B')
/ NULLIF((SELECT avg_price FROM variants WHERE variant = 'A'), 0)), 0) AS pe;Лучше эксперимент через дискретное изменение цены — это даёт чистую elasticity.
По сегменту
Enterprise vs SMB обычно разные:
SELECT
customer_segment,
AVG(price_elasticity) AS avg_pe,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY price_elasticity) AS median_pe
FROM elasticity_per_period
WHERE price_elasticity BETWEEN -10 AND 10 -- отсечь outliers
GROUP BY customer_segment;Enterprise PE обычно −0.3 до −0.7 (неэластично — нужны для работы). SMB −1.0 до −2.0 (эластично, легко уходят).
Частые ошибки
Ошибка 1. Игнорировать confounders. Зимняя распродажа → цена ↓ и quantity ↑ — но не из-за цены, а из-за сезона. Контролируйте период.
Ошибка 2. Считать elasticity per single observation. Нужны хотя бы 2 точки price/quantity. Без variance — нет elasticity.
Ошибка 3. Знак. Эластичность отрицательная для normal goods. Положительная — для Veblen goods (раритеты) или ошибка в данных.
Ошибка 4. Не контролировать на cohort. Новые vs существующие customers могут иметь разную elasticity. Cohort-aware расчёт.
Ошибка 5. Игнорировать competitor pricing. Если конкурент уронил цены, у вас quantity упал — не из-за вашей цены.
Связанные темы
- Как посчитать conversion uplift в SQL
- Как посчитать AOV в SQL
- Как посчитать revenue в SQL
- Как посчитать t-test в SQL
FAQ
Какое значение PE «нормально»?
Для SaaS −0.5 до −1.5 типично. > −1 (по модулю) — неэластично, можно повышать.
Как делать pricing-эксперимент?
Случайных новых юзеров делите на разные цены. Существующих не трогать — повышение цен на текущую базу это отдельная задача со своими рисками.
Что если PE положительный?
Ошибка данных, Veblen good, или confounding period.
Elasticity и revenue?
При PE = −1 — revenue константен при изменении цены. PE > −1 (неэластично) — повышение цены растит revenue. PE < −1 — понижение цены растит revenue.
Cross-price elasticity?
Как продажи product A зависят от цены B. Substitutes — положительная PE, complements — отрицательная.