## БЛОК ТЕОРИИ: Бизнес-мышление и метрики Это **самый важный блок** для прохождения собеседований. Именно здесь проверяют, умеет ли кандидат **мыслить как бизнес**, а не просто писать код. Давайте разберем **всю теорию** максимально подробно, с формулами, примерами и скриптами для Northwind. ### ТЕМА 1. Продуктовые метрики Эти метрики помогают понять, **как пользователи взаимодействуют с продуктом**, насколько они лояльны и сколько денег приносят. --- #### 1.1 DAU / WAU / MAU (Активная аудитория) | Метрика | Расшифровка | Что показывает | | :--- | :--- | :--- | | **DAU** | Daily Active Users | Сколько уникальных пользователей зашли в день | | **WAU** | Weekly Active Users | Сколько уникальных пользователей зашли за неделю | | **MAU** | Monthly Active Users | Сколько уникальных пользователей зашли за месяц | **Зачем нужны:** - Показывают **масштаб** аудитории - Помогают отслеживать **тренды** (рост/падение) - Используются для расчета других метрик **Пример из ритейла (М.Видео):** - DAU = 50 000 человек заходят на сайт ежедневно - MAU = 500 000 уникальных посетителей в месяц **Как посчитать в SQL (Northwind):** ```sql -- Ежедневное количество уникальных клиентов, сделавших заказ SELECT order_date, COUNT(DISTINCT customer_id) AS dau FROM orders GROUP BY order_date ORDER BY order_date; ``` --- ### 1.2 Stickiness (Липкость) **Определение:** Показывает, **насколько часто** пользователи возвращаются в продукт. **Формула:** ``` Stickiness = DAU / MAU × 100% ``` | Значение | Интерпретация | | :--- | :--- | | **> 50%** | 🔥 Супер-липкий продукт (пользователи заходят почти каждый день) | | **20-50%** | 👍 Хорошая липкость | | **< 20%** | ⚠️ Низкая липкость (пользователи приходят редко) | **Пример:** - DAU = 10 000 - MAU = 50 000 - Stickiness = 10 000 / 50 000 = **20%** **Вывод:** В среднем пользователь заходит 6 раз в месяц (20% от 30 дней). **Как посчитать в SQL:** ```sql WITH daily_users AS ( SELECT order_date, COUNT(DISTINCT customer_id) AS dau FROM orders GROUP BY order_date ), monthly_users AS ( SELECT DATE_TRUNC('month', order_date) AS month, COUNT(DISTINCT customer_id) AS mau FROM orders GROUP BY DATE_TRUNC('month', order_date) ) SELECT AVG(d.dau) / m.mau * 100 AS stickiness FROM daily_users d CROSS JOIN monthly_users m GROUP BY m.mau; ``` --- #### 1.3 Retention (Удержание) **Определение:** Доля пользователей, которые **вернулись** в продукт через определенное время. **Cohort Analysis (Когортный анализ):** - **Когорта** — группа пользователей, объединенная по времени (например, все, кто зарегистрировался в январе) - **Retention** — сколько из них вернулись через 1, 2, 3... месяца **Пример:** | Месяц регистрации | Зарегистрировалось | Вернулись через 1 мес | Retention 1 мес | | :--- | :--- | :--- | :--- | | Январь 2025 | 1000 | 400 | 40% | | Февраль 2025 | 1200 | 480 | 40% | | Март 2025 | 900 | 270 | 30% | **Вывод:** Retention падает → нужно улучшать продукт. **Как посчитать в SQL (Northwind):** ```sql -- Когортный анализ: первый заказ клиента и его возвращаемость WITH first_orders AS ( SELECT customer_id, MIN(order_date) AS first_order_date FROM orders GROUP BY customer_id ), cohorts AS ( SELECT customer_id, DATE_TRUNC('month', first_order_date) AS cohort_month FROM first_orders ), order_months AS ( SELECT o.customer_id, c.cohort_month, DATE_TRUNC('month', o.order_date) AS order_month, EXTRACT(MONTH FROM AGE(o.order_date, c.cohort_month)) AS month_number FROM orders o JOIN cohorts c ON o.customer_id = c.customer_id ) SELECT cohort_month, month_number, COUNT(DISTINCT customer_id) AS retained_users FROM order_months GROUP BY cohort_month, month_number ORDER BY cohort_month, month_number; ``` --- #### 1.4 Churn Rate (Отток) **Определение:** Доля пользователей, которые **перестали пользоваться** продуктом. **Формула:** ``` Churn Rate = (Клиентов в начале - Клиентов в конце) / Клиентов в начале × 100% ``` **Пример:** - В начале месяца: 10 000 клиентов - В конце месяца: 9 000 клиентов - Churn Rate = (10 000 - 9 000) / 10 000 = **10%** **Как снизить Churn:** - Улучшить продукт - Внедрить программу лояльности - Сделать персонализированные предложения --- #### 1.5 ARPU и ARPPU (Доход на пользователя) | Метрика | Расшифровка | Формула | | :--- | :--- | :--- | | **ARPU** | Average Revenue Per User | Выручка / Все пользователи | | **ARPPU** | Average Revenue Per Paying User | Выручка / Платящие пользователи | **Пример:** - Выручка за месяц = 1 000 000 ₽ - Всего пользователей = 100 000 - Платящих пользователей = 10 000 **ARPU** = 1 000 000 / 100 000 = **10 ₽** **ARPPU** = 1 000 000 / 10 000 = **100 ₽** **Вывод:** ARPPU в 10 раз больше ARPU → монетизация держится на небольшой группе. --- #### 1.6 LTV (Lifetime Value) — Пожизненная ценность клиента **Определение:** Сколько денег принесет клиент за всё время взаимодействия с компанией. **Упрощенная формула:** ``` LTV = Средний чек × Частота покупок × Время жизни клиента ``` **Точная формула:** ``` LTV = ARPU × (1 / Churn Rate) ``` **Пример:** - ARPU = 1000 ₽ в месяц - Churn Rate = 5% (0.05) - LTV = 1000 / 0.05 = **20 000 ₽** **Как увеличить LTV:** 1. Увеличить средний чек (апселл/кросс-селл) 2. Увеличить частоту покупок 3. Снизить отток (увеличить время жизни) **Как посчитать LTV в Northwind:** ```sql -- LTV каждого клиента WITH customer_metrics AS ( SELECT c.customer_id, COUNT(DISTINCT o.order_id) AS order_count, AVG(od.quantity * od.unit_price * (1 - od.discount)) AS avg_check, SUM(od.quantity * od.unit_price * (1 - od.discount)) AS total_spent, MAX(o.order_date) - MIN(o.order_date) AS customer_lifetime_days FROM customers c JOIN orders o ON c.customer_id = o.customer_id JOIN order_details od ON o.order_id = od.order_id GROUP BY c.customer_id ) SELECT customer_id, total_spent AS ltv, order_count, avg_check, customer_lifetime_days FROM customer_metrics ORDER BY ltv DESC; ``` --- ### ТЕМА 2. МАРКЕТИНГОВЫЕ МЕТРИКИ Эти метрики помогают оценить **эффективность рекламных кампаний** и **окупаемость маркетинговых бюджетов**. --- #### 2.1 CAC (Customer Acquisition Cost) — Стоимость привлечения клиента **Определение:** Сколько денег нужно потратить, чтобы привлечь одного нового клиента. **Формула:** ``` CAC = Затраты на маркетинг / Количество новых клиентов ``` **Пример:** - Потратили на рекламу = 500 000 ₽ - Привлекли 1000 новых клиентов - CAC = 500 000 / 1000 = **500 ₽** **Что такое "хороший" CAC?** - CAC должен быть **меньше LTV** (иначе вы работаете в убыток) - Идеально: LTV > 3 × CAC --- #### 2.2 ROMI (Return on Marketing Investment) **Определение:** Возврат на инвестиции в маркетинг. Показывает, сколько рублей прибыли приносит 1 рубль, потраченный на маркетинг. **Формула:** ``` ROMI = (Выручка от маркетинга - Затраты на маркетинг) / Затраты на маркетинг × 100% ``` **Пример:** - Потратили на рекламу = 100 000 ₽ - Получили выручку = 300 000 ₽ - ROMI = (300 000 - 100 000) / 100 000 = **200%** | ROMI | Интерпретация | | :--- | :--- | | **> 100%** | 🟢 Отлично (каждый рубль приносит 2+ рубля) | | **0-100%** | 🟡 Окупается, но не очень эффективно | | **< 0%** | 🔴 Убыточно (тратим больше, чем зарабатываем) | --- #### 2.3 ROI (Return on Investment) **Определение:** Общая окупаемость инвестиций (не только маркетинговых). **Формула:** ``` ROI = (Доход - Затраты) / Затраты × 100% ``` --- #### 2.4 CPC, CPM, CTR (Контекстная реклама) | Метрика | Расшифровка | Формула | Пример | | :--- | :--- | :--- | :--- | | **CPC** | Cost Per Click | Бюджет / Количество кликов | 10 ₽ за клик | | **CPM** | Cost Per Mille (1000 показов) | Бюджет / Показы × 1000 | 200 ₽ за 1000 показов | | **CTR** | Click-Through Rate | Клики / Показы × 100% | 2% (20 кликов на 1000 показов) | **Взаимосвязь:** ``` CPC = CPM / (CTR × 10) ``` **Пример:** - CPM = 200 ₽ - CTR = 2% (0.02) - CPC = 200 / (0.02 × 1000) = **10 ₽** --- ### ТЕМА 3. РИТЕЙЛ-МЕТРИКИ Это метрики, специфичные для розничной торговли (как в Ленте, М.Видео, Ригле). --- #### 3.1 ABC-XYZ Анализ **Определение:** Метод классификации товаров по двум критериям: - **ABC** — по вкладу в выручку - **XYZ** — по стабильности продаж | Категория ABC | Описание | Доля в выручке | | :--- | :--- | :--- | | **A** | Самые важные товары | ~80% | | **B** | Средние товары | ~15% | | **C** | Наименее важные товары | ~5% | | Категория XYZ | Описание | Коэффициент вариации | | :--- | :--- | :--- | | **X** | Стабильные продажи | < 10% | | **Y** | Сезонные/волатильные | 10-25% | | **Z** | Нерегулярные продажи | > 25% | **Матрица ABC-XYZ:** | | X (стабильные) | Y (сезонные) | Z (случайные) | | :--- | :--- | :--- | :--- | | **A** (80% выручки) | 🔥 **AX** — Главные товары, держать всегда | **AY** — Планировать по сезону | **AZ** — Анализировать причины | | **B** (15% выручки) | **BX** — Стабильные, держать | **BY** — Планировать | **BZ** — Требуют внимания | | **C** (5% выручки) | **CX** — Можно держать | **CY** — Можно сократить | **CZ** — 🗑️ Выводить из ассортимента | **Как посчитать ABC-XYZ в SQL (Northwind):** ```sql -- ABC-XYZ анализ товаров WITH product_sales AS ( SELECT p.product_id, p.product_name, SUM(od.quantity * od.unit_price * (1 - od.discount)) AS total_revenue, COUNT(DISTINCT o.order_id) AS order_count, STDDEV(od.quantity) AS sales_variation FROM products p JOIN order_details od ON p.product_id = od.product_id JOIN orders o ON od.order_id = o.order_id GROUP BY p.product_id, p.product_name ), abc_classification AS ( SELECT *, PERCENT_RANK() OVER (ORDER BY total_revenue DESC) AS revenue_percentile FROM product_sales ) SELECT product_name, total_revenue, CASE WHEN revenue_percentile <= 0.8 THEN 'A' WHEN revenue_percentile <= 0.95 THEN 'B' ELSE 'C' END AS abc_category, CASE WHEN sales_variation < 0.1 THEN 'X' WHEN sales_variation < 0.25 THEN 'Y' ELSE 'Z' END AS xyz_category FROM abc_classification ORDER BY total_revenue DESC; ``` --- #### 3.2 Средний чек (Average Check / AOV) **Определение:** Средняя сумма одной покупки. **Формула:** ``` Средний чек = Выручка / Количество заказов ``` **Как увеличить средний чек:** 1. Апселл (предложить более дорогой товар) 2. Кросс-селл (предложить дополнительные товары) 3. Скидки за минимальную сумму заказа **SQL в Northwind:** ```sql SELECT AVG(order_total) AS avg_check FROM ( SELECT o.order_id, SUM(od.quantity * od.unit_price * (1 - od.discount)) AS order_total FROM orders o JOIN order_details od ON o.order_id = od.order_id GROUP BY o.order_id ) AS order_totals; ``` --- #### 3.3 Конверсия (Conversion Rate) **Определение:** Доля пользователей, которые совершили целевое действие. **Примеры конверсии в ритейле:** - Посетитель сайта → Добавил товар в корзину - Добавил в корзину → Оформил заказ - Посетитель магазина → Совершил покупку **Формула:** ``` Конверсия = Целевые действия / Всего пользователей × 100% ``` **Пример:** - 1000 посетителей сайта - 50 оформили заказ - Конверсия = 50 / 1000 = **5%** --- #### 3.4 Воронка продаж (Sales Funnel) **Определение:** Путь клиента от первого касания до покупки. **Пример воронки для интернет-магазина:** | Этап | Количество | Конверсия (от этапа к этапу) | | :--- | :--- | :--- | | Посетили сайт | 10 000 | - | | Посмотрели товар | 4 000 | 40% | | Добавили в корзину | 1 000 | 25% | | Оформили заказ | 200 | 20% | | Оплатили | 150 | 75% | | **Общая конверсия** | **1.5%** | - | **Где падает воронка?** На этапе "корзина → заказ" (20%) — возможно, сложная форма оформления. **SQL в Northwind (упрощенная воронка):** ```sql SELECT COUNT(DISTINCT customer_id) AS customers, COUNT(DISTINCT order_id) AS orders, COUNT(DISTINCT order_id)::FLOAT / COUNT(DISTINCT customer_id) AS conversion_rate FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id; ``` --- #### 3.5 Товарооборот (Turnover / T/O) **Определение:** Общая стоимость проданных товаров за период. **Формула:** ``` Товарооборот = Сумма всех продаж ``` **Не путать с выручкой!** Выручка = Товарооборот - возвраты - скидки. **SQL в Northwind:** ```sql SELECT SUM(od.quantity * od.unit_price * (1 - od.discount)) AS turnover FROM order_details od; ``` --- #### 3.6 Маржинальность (Margin) **Определение:** Доля прибыли в цене товара. **Формула:** ``` Маржинальность = (Цена продажи - Себестоимость) / Цена продажи × 100% ``` **Пример:** - Продаем товар за 1000 ₽ - Себестоимость = 700 ₽ - Маржинальность = (1000 - 700) / 1000 = **30%** **Что важно:** Маржинальность показывает, сколько денег остается компании после покрытия прямых затрат. --- #### 3.7 Оборачиваемость склада (Inventory Turnover) **Определение:** Сколько раз за период товар продается и заменяется на складе. **Формула:** ``` Оборачиваемость = Себестоимость проданных товаров / Средний остаток на складе ``` **Пример:** - Себестоимость проданных товаров за год = 10 000 000 ₽ - Средний остаток на складе = 1 000 000 ₽ - Оборачиваемость = **10 раз в год** **Интерпретация:** - Высокая оборачиваемость → товар быстро продается (хорошо) - Низкая оборачиваемость → товар залеживается (плохо, увеличивает затраты на хранение) --- #### 3.8 Out-of-Stock (OOS) **Определение:** Доля времени, когда товара нет в наличии. **Формула:** ``` OOS = Дни без товара / Всего дней × 100% ``` **Почему это плохо:** - Потеря продаж (клиент уходит к конкуренту) - Снижение лояльности - Ухудшение метрик (заниженный средний чек) **SQL в Northwind (имитация):** ```sql -- Товары, которые закончились (units_in_stock = 0) SELECT product_name, units_in_stock FROM products WHERE units_in_stock = 0; ``` --- ### ТЕМА 4. ПРОЦЕССНЫЙ ПОДХОД (ДЕКОМПОЗИЦИЯ) **Декомпозиция** — это разбиение сложной задачи на простые составляющие. --- #### 4.1 Как искать причину падения метрики? **Метод "Дерево факторов":** ``` Падение выручки (-5%) │ ├─ Продажи упали │ ├─ Меньше клиентов │ │ ├─ Меньше трафика │ │ └─ Меньше конверсия │ └─ Меньше средний чек │ ├─ Дешевые товары │ └─ Меньше товаров в корзине │ └─ Цены упали ├─ Скидки └─ Снижение цен ``` --- #### 4.2 Формула декомпозиции ``` Выручка = Трафик × Конверсия × Средний чек ``` **Пример расчета:** | Показатель | Прошлый месяц | Текущий месяц | Изменение | | :--- | :--- | :--- | :--- | | Трафик | 10 000 | 9 500 | -5% | | Конверсия | 5% (0.05) | 5.2% (0.052) | +4% | | Средний чек | 1000 ₽ | 950 ₽ | -5% | | **Выручка** | **500 000** | **469 300** | **-6.14%** | **Что делать:** 1. Трафик упал на 5% → возможно, проблема с рекламой 2. Средний чек упал на 5% → возможно, переключение на дешевые товары --- #### 4.3 Пример ответа на собеседовании **Вопрос:** *"Наша выручка упала на 5% за месяц. Как будешь искать причину?"* **Правильный ответ (структурированный):** 1. **Сначала проверю данные:** - Нет ли технических ошибок (сбой в базе, неправильная выгрузка) - Сравню с аналогичным периодом прошлого года (сезонность) 2. **Разложу выручку на факторы:** - Выручка = Количество заказов × Средний чек - Количество заказов = Активные клиенты × Частота покупок - Активные клиенты = Новые + Вернувшиеся - Отток 3. **Проверю каждый фактор:** - Не упал ли трафик? (маржа, конверсия) - Не упал ли средний чек? (скидки, смена ассортимента) - Не вырос ли отток? (конкуренты, сервис) 4. **Построю воронку:** - Посетители → Корзина → Заказ → Оплата - На каком этапе падение? 5. **Сделаю выводы и предложу гипотезы:** - Если упал трафик → бюджет на рекламу - Если упала конверсия → UX/цена - Если упал средний чек → кросс-селлы/апселлы --- ### ИТОГОВАЯ ШПАРГАЛКА ДЛЯ СОБЕСЕДОВАНИЯ | Метрика | Формула | Зачем | | :--- | :--- | :--- | | **DAU/MAU** | Количество пользователей в день/месяц | Оценить размер аудитории | | **Stickiness** | DAU / MAU × 100% | Понять частоту возврата | | **Retention** | Вернулись / Зарегистрировались | Оценить удержание | | **Churn** | (Начало - Конец) / Начало × 100% | Оценить отток | | **ARPU** | Выручка / Все пользователи | Доход на всех | | **ARPPU** | Выручка / Платящие | Доход на платящих | | **LTV** | ARPU / Churn | Пожизненная ценность | | **CAC** | Затраты / Новые клиенты | Стоимость привлечения | | **ROMI** | (Выручка - Затраты) / Затраты × 100% | Окупаемость маркетинга | | **Средний чек** | Выручка / Количество заказов | Типичный размер покупки | | **Конверсия** | Целевые действия / Всего × 100% | Эффективность воронки | | **ABC-XYZ** | Матрица классификации | Управление ассортиментом | | **Маржинальность** | (Цена - Себест.) / Цена × 100% | Прибыльность товара | | **Оборачиваемость** | Себест. / Средний остаток | Эффективность склада | --- ### ПРАКТИЧЕСКОЕ ЗАДАНИЕ ДЛЯ СТУДЕНТА На основе Northwind напишите отчет для CEO компании: 1. **Выручка** за 1997 год 2. **Средний чек** по месяцам 3. **Количество уникальных клиентов** (MAU по месяцам) 4. **Топ-5 товаров** по выручке (категория A) 5. **Товары, которые не продавались** (Out-of-Stock потенциальные проблемы) 6. **LTV клиентов** (Топ-10 самых ценных) **Решение:** ```sql -- 1. Выручка за 1997 год SELECT SUM(od.quantity * od.unit_price * (1 - od.discount)) AS total_revenue_1997 FROM orders o JOIN order_details od ON o.order_id = od.order_id WHERE EXTRACT(YEAR FROM o.order_date) = 1997; -- 2. Средний чек по месяцам SELECT DATE_TRUNC('month', o.order_date) AS month, AVG(od.quantity * od.unit_price * (1 - od.discount)) AS avg_check FROM orders o JOIN order_details od ON o.order_id = od.order_id WHERE EXTRACT(YEAR FROM o.order_date) = 1997 GROUP BY DATE_TRUNC('month', o.order_date) ORDER BY month; -- 3. Количество уникальных клиентов по месяцам SELECT DATE_TRUNC('month', order_date) AS month, COUNT(DISTINCT customer_id) AS unique_customers FROM orders WHERE EXTRACT(YEAR FROM order_date) = 1997 GROUP BY DATE_TRUNC('month', order_date) ORDER BY month; -- 4. Топ-5 товаров по выручке SELECT p.product_name, SUM(od.quantity * od.unit_price * (1 - od.discount)) AS revenue FROM products p JOIN order_details od ON p.product_id = od.product_id GROUP BY p.product_id, p.product_name ORDER BY revenue DESC LIMIT 5; -- 5. Товары, которые не продавались SELECT product_name FROM products WHERE product_id NOT IN ( SELECT DISTINCT product_id FROM order_details ); -- 6. Топ-10 LTV клиентов SELECT c.customer_id, c.company_name, SUM(od.quantity * od.unit_price * (1 - od.discount)) AS ltv FROM customers c JOIN orders o ON c.customer_id = o.customer_id JOIN order_details od ON o.order_id = od.order_id GROUP BY c.customer_id, c.company_name ORDER BY ltv DESC LIMIT 10; ```