Задачи аналитика данных: 12 рабочих вопросов, SQL и ответы
Какие задачи решает аналитик данных на работе: 12 вопросов от коллег — от падения DAU до A/B-теста и MRR — с уточнением, SQL-запросом, ответом и выводом для чата.
Содержание статьи
Описания профессии обычно перечисляют навыки: SQL, Python, статистика, BI. Но работа аналитика данных состоит не из навыков, а из вопросов, которые приходят от коллег: почему упало, откуда выросло, работает ли новая функция, сколько мы зарабатываем. Здесь 12 таких вопросов на одном продукте — SaaS-сервисе из учебной базы SQL-курса. Для каждого показано, что нужно уточнить до запроса, какой SQL отвечает на вопрос, какое число получается и что написать в ответ. Половина вопросов заканчивается не тем выводом, который напрашивался: так чаще всего и бывает на работе. Все запросы можно повторить в песочнице курса и получить те же числа.
Из чего состоит неделя аналитика
Задачи аналитика продукта делятся на четыре потока. Мониторинг: следить за ключевыми метриками и первым замечать, что с ними что-то не так. Вопросы: отвечать менеджерам, маркетингу и руководству, когда число их удивило. Эксперименты: считать A/B-тесты и говорить, можно ли верить результату. Данные: проверять, что таблицы соответствуют тому, что о них думают.
В каждом потоке работа идёт по одной схеме. Вопрос приходит словами, иногда эмоциональными: «всё упало». Аналитик уточняет, что именно считать и за какой период, пишет запрос, получает число и переводит его обратно в слова — коротко, с выводом и оговорками. Запрос занимает меньшую часть времени. Больше уходит на уточнение и на проверку, что ответ не врёт.
Вопросы ниже заданы продукту, где люди регистрируются, открывают приложение, создают рабочие пространства и отчёты и платят за подписку. Регистрации идут с 1 июня по 29 августа 2026 года, выгрузка закрыта 30 августа в 13:00. Данные те же, что в песочнице SQL-курса.
| Поток | Вопросы | Чем кончилось |
|---|---|---|
| мониторинг | активные пользователи, провал в воскресенье, падение DAU | оба «падения» — свойства календаря и выгрузки, а не продукта |
| вопросы | всплеск регистраций, деньги по каналам, воронка, возврат, просадка retention | просадка retention — эффект нового канала |
| эксперименты | онбординг с чек-листом | эффект есть только на десктопе |
| деньги и данные | MRR, отток, проверка перед отчётом | статус подписки нельзя читать как отток без уточнения |
1. «Сколько у нас активных пользователей?»
Уточнение. «Активный» — это кто? Любое событие в продукте или только открытие приложения? И за какой период: день, неделя, месяц? Без ответа на эти вопросы любое число будет правильным и бесполезным. Договоримся считать активностью открытие приложения, а за период взять август.
Ответ. Средний DAU за 29 полных дней августа — 470,9 человека, MAU за август — 4 109. Если считать активностью любое событие, DAU получится 486,9: разница небольшая, но в отчётах разных команд такие расхождения потом ищут неделями. 30 августа в расчёт не входит: выгрузка обрывается в 13:00.
Что сказать: «В августе в среднем 471 человек в день открывал продукт, за месяц — 4 109 разных людей. Считаю по открытию приложения; если нужна другая активность, пересчитаю».
WITH daily AS (
SELECT
CAST(event_time AS DATE) AS day,
count(DISTINCT user_id) FILTER (WHERE event_name = 'app_open') AS dau_open,
count(DISTINCT user_id) AS dau_any_event
FROM events
WHERE event_time >= TIMESTAMP '2026-08-01'
AND event_time < TIMESTAMP '2026-08-30'
GROUP BY day
)
SELECT
round(avg(dau_open), 1) AS avg_dau_open,
round(avg(dau_any_event), 1) AS avg_dau_any_event,
(SELECT count(DISTINCT user_id)
FROM events
WHERE event_name = 'app_open'
AND event_time >= TIMESTAMP '2026-08-01'
AND event_time < TIMESTAMP '2026-09-01') AS mau_august
FROM daily;
-- 470.9 | 486.9 | 41092. «В воскресенье регистраций в два с половиной раза меньше, чем в пятницу. Что сломалось?»
Уточнение. С чем сравнивать воскресенье? В пятницу, 21 августа, пришли 83 человека, в воскресенье, 23-го, — 33. Сравнение с пятницей подразумевает, что дни недели одинаковы. Для B2B-инструмента, который открывают с рабочего места, это заранее неверно. Честное сравнение — воскресенье с прошлыми воскресеньями.
Ответ. В будни в среднем приходит от 58,7 до 63,7 человека в день, в субботу — 26,9, в воскресенье — 23,6. За весь период по понедельникам зарегистрировались 763 человека, по воскресеньям — 283. Это недельный цикл, он повторяется каждую неделю. А последние воскресенья растут: 28, 30, 31 и 33 регистрации в августе.
Что сказать: «Ничего не сломалось: в выходные у нас всегда вдвое-втрое меньше регистраций. Воскресенье 23 августа — 33 человека, на 6% больше прошлого воскресенья. Для мониторинга предлагаю сравнивать день с тем же днём прошлой недели».
Среднее за 12–13 одинаковых дней недели с 1 июня по 29 августа 2026 года. Учебная база SQL-курса.
SELECT
extract(isodow FROM signup_date) AS weekday, -- 1 = понедельник, 7 = воскресенье
count(*) AS signups,
count(DISTINCT signup_date) AS days,
round(count(*) * 1.0 / count(DISTINCT signup_date), 1) AS per_day
FROM users
GROUP BY weekday
ORDER BY weekday;
-- пн 763 / 58.7, вт 773 / 59.5, ср 819 / 63.0, чт 828 / 63.7,
-- пт 797 / 61.3, сб 350 / 26.9, вс 283 / 23.6 (воскресений 12)3. «Вчера DAU упал вдвое — что случилось?»
Уточнение. Какой день «вчера» и полностью ли он попал в данные? Это первое, что стоит проверить при любом резком падении в последней точке графика. Посмотрите на время последнего события.
Ответ. 30 августа DAU — 221 человек, днём раньше — 506. Но последнее событие 30 августа записано в 12:59: выгрузка закрыта в 13:00. Если сравнить одинаковые часы, до 13:00 29 августа приложение открыли 228 человек, 30 августа — 221. Разница в 3%, а не вдвое.
Что сказать: «Падения нет: 30 августа в данных только до 13:00. Если сравнивать те же часы, DAU на уровне предыдущего дня. Чтобы такое не пугало, на графике последний неполный день лучше не показывать или помечать».
SELECT
CAST(event_time AS DATE) AS day,
count(DISTINCT user_id) AS dau,
count(DISTINCT user_id) FILTER (WHERE extract(hour FROM event_time) < 13) AS dau_before_13,
max(event_time) AS last_event
FROM events
WHERE event_name = 'app_open'
AND event_time >= TIMESTAMP '2026-08-28'
GROUP BY day
ORDER BY day;
-- 08-28: 567 | 248 | 20:59
-- 08-29: 506 | 228 | 20:54
-- 08-30: 221 | 221 | 12:594. «Откуда всплеск регистраций 15–16 июля и хорошие ли это пользователи?»
Уточнение. «Откуда» — какой канал? «Хорошие» — активируются и платят так же, как обычно? Сравнивать надо с соседними буднями — 13, 14 и 17 июля, а не со средним за месяц, куда попадают выходные.
Ответ. 15 и 16 июля пришли 99 и 100 человек против 59–61 в соседние будни. Дней разное число, поэтому сравниваем регистрации в день: выросли все каналы сразу, от referral (с 13,0 до 19,0 в день) до partner (с 9,7 до 18,5). Значит, это не бюджет одного платного канала. Доля активировавшихся — 54,3% против 55,9% в соседние дни, доля платящих — 22,1% против 24,0%: пользователи примерно такие же.
Что сказать: «Всплеск прошёл по всем каналам сразу, поэтому в наших данных его источника не видно — похоже на внешнее упоминание или рассылку. Уточню у маркетинга. Качество пользователей обычное: активируются и платят на уровне соседних дней». Хороший ответ здесь честно говорит, чего данные не знают.
| Дни | Всего в день | organic | referral | partner | paid_search | Активация | Платят |
|---|---|---|---|---|---|---|---|
| 15–16 июля | 99,5 | 32,0 | 19,0 | 18,5 | 30,0 | 54,3% | 22,1% |
| 13, 14 и 17 июля | 59,7 | 18,3 | 13,0 | 9,7 | 18,7 | 55,9% | 24,0% |
SELECT
CASE WHEN signup_date IN (DATE '2026-07-15', DATE '2026-07-16')
THEN 'всплеск' ELSE 'соседние будни' END AS days,
count(DISTINCT signup_date) AS n_days,
round(count(*) * 1.0 / count(DISTINCT signup_date), 1) AS per_day,
round(count(*) FILTER (WHERE channel = 'organic') * 1.0 / count(DISTINCT signup_date), 1) AS organic,
round(count(*) FILTER (WHERE channel = 'referral') * 1.0 / count(DISTINCT signup_date), 1) AS referral,
round(count(*) FILTER (WHERE channel = 'partner') * 1.0 / count(DISTINCT signup_date), 1) AS partner,
round(count(*) FILTER (WHERE channel = 'paid_search') * 1.0 / count(DISTINCT signup_date), 1) AS paid_search,
round(100.0 * count(*) FILTER (WHERE user_id IN (
SELECT user_id FROM events WHERE event_name = 'workspace_created'
)) / count(*), 1) AS activation_pct,
round(100.0 * count(*) FILTER (WHERE user_id IN (
SELECT user_id FROM payments
)) / count(*), 1) AS payer_pct
FROM users
WHERE signup_date BETWEEN DATE '2026-07-13' AND DATE '2026-07-17'
GROUP BY days
ORDER BY days;
-- всплеск: 2 дня | 99.5 в день | 32.0 | 19.0 | 18.5 | 30.0 | 54.3 | 22.1
-- соседние будни: 3 дня | 59.7 в день | 18.3 | 13.0 | 9.7 | 18.7 | 55.9 | 24.05. «Какой канал приносит деньги?»
Уточнение. Деньги на регистрацию, на платящего или всего? Для решения о бюджете обычно важна выручка на одну регистрацию — ARPU канала. И вторая оговорка: paid_search запущен 1 июля, у его пользователей было меньше времени на оплату, чем у остальных.
Ответ. Выручка на регистрацию: referral — $8,99, organic — $8,08, partner — $5,81, paid_search — $2,43. При этом платящий из paid_search тратит почти столько же, сколько другие: $28,69 против $33,55–34,42. Разница не в чеке, а в том, что платят редко: 86 человек из 1 015. Чтобы убрать влияние срока, сравним каналы на одном периоде: у зарегистрированных с 1 июля по 16 августа в первые 14 дней платят 20,6% из referral и 6,2% из paid_search. Разрыв остаётся.
Что сказать: «Больше всего на регистрацию приносит referral, меньше всего — paid_search: в 3,7 раза меньше. Проблема paid_search не в размере чека, а в том, что платит каждый двенадцатый. Прежде чем решать про бюджет, нужна стоимость привлечения — её в наших данных нет».
WITH revenue AS (
SELECT user_id, sum(amount) AS revenue
FROM payments
GROUP BY user_id
)
SELECT
u.channel,
count(*) AS signups,
count(r.user_id) AS payers,
coalesce(sum(r.revenue), 0) AS revenue,
round(coalesce(sum(r.revenue), 0) / count(*), 2) AS arpu,
round(sum(r.revenue) / count(r.user_id), 2) AS arppu
FROM users u
LEFT JOIN revenue r ON r.user_id = u.user_id
GROUP BY u.channel
ORDER BY arpu DESC;
-- referral 1037 | 278 | 9326 | 8.99 | 33.55
-- organic 1747 | 410 | 14114 | 8.08 | 34.42
-- partner 814 | 138 | 4732 | 5.81 | 34.29
-- paid_search 1015 | 86 | 2467 | 2.43 | 28.696. «Где теряются новые пользователи?»
Уточнение. Какие шаги считать воронкой? Здесь естественный путь такой: открыл приложение → создал рабочее пространство → создал отчёт. Конверсию каждого шага считаем от предыдущего шага и по людям, а не по событиям.
Ответ. Приложение открыли все 4 613 зарегистрированных, рабочее пространство создали 2 750 (59,61%), отчёт — 1 775, это 64,55% от создавших пространство. Главная потеря — на первом шаге, и она сильно зависит от канала: referral создают пространство в 74,73% случаев, paid_search — в 37,04%. Второй шаг во всех каналах почти одинаков, от 62,71% до 66,04%.
Что сказать: «Теряем на создании рабочего пространства: его делает 60% новых пользователей. Второй шаг проходят две трети, и он от канала не зависит. Значит, работать стоит с первым шагом, и в первую очередь с трафиком paid_search».
Все регистрации с 1 июня по 29 августа 2026 года. Учебная база SQL-курса.
WITH flags AS (
SELECT
u.user_id,
u.channel,
max(CASE WHEN e.event_name = 'workspace_created' THEN 1 ELSE 0 END) AS workspace,
max(CASE WHEN e.event_name = 'report_created' THEN 1 ELSE 0 END) AS report
FROM users u
LEFT JOIN events e ON e.user_id = u.user_id
GROUP BY u.user_id, u.channel
)
SELECT
channel,
count(*) AS signups,
round(100.0 * sum(workspace) / count(*), 2) AS workspace_pct,
round(100.0 * sum(report) / sum(workspace), 2) AS report_of_workspace_pct
FROM flags
GROUP BY channel
ORDER BY workspace_pct DESC;
-- referral 74.73 | 62.71, organic 66.74 | 66.04,
-- partner 53.19 | 64.90, paid_search 37.04 | 63.307. «Возвращаются ли пользователи после первого дня?»
Уточнение. «Вернулся» — открыл приложение на следующий календарный день после регистрации. Считать можно только тех, у кого этот день уже прошёл целиком: последний полный день в данных — 29 августа, значит, берём регистрации по 28 августа.
Ответ. D1 retention — 53,42%: вернулись 2 444 из 4 575 человек. По каналам разброс почти вдвое: referral — 66,08%, organic — 60,55%, partner — 45,54%, paid_search — 34,46%. Порядок каналов тот же, что в активации и оплате: paid_search отстаёт везде.
Что сказать: «На следующий день возвращается чуть больше половины новых пользователей. Лучше всех — пришедшие по рекомендации, хуже всех — из платного поиска: каждый третий». Если спросят про D7 — это та же логика, только отсечение по 22 августа.
WITH d1 AS (
SELECT
u.user_id,
u.channel,
max(CASE
WHEN e.event_name = 'app_open'
AND CAST(e.event_time AS DATE) = u.signup_date + 1
THEN 1 ELSE 0
END) AS returned
FROM users u
LEFT JOIN events e ON e.user_id = u.user_id
WHERE u.signup_date <= DATE '2026-08-28'
GROUP BY u.user_id, u.channel
)
SELECT
channel,
count(*) AS users,
round(100.0 * sum(returned) / count(*), 2) AS d1_pct
FROM d1
GROUP BY channel
ORDER BY d1_pct DESC;
-- referral 1029 | 66.08, organic 1734 | 60.55,
-- partner 808 | 45.54, paid_search 1004 | 34.468. «Почему retention просел в июле?»
Уточнение. Просел у кого — у всех пользователей или внутри каждого канала? Если состав пользователей изменился, общая метрика может упасть, даже если ни одна группа не стала хуже. А в июле состав изменился: 1 июля запустили paid_search.
Ответ. D1 по месяцам регистрации: июнь — 57,01%, июль — 51,01%, август — 53,58%. Без paid_search те же месяцы дают 57,01%, 58,04% и 60,75%: старые каналы не просели, а даже подросли. Весь спад — это новый канал с D1 около 34–35%, который в июле дал 28,8% регистраций. На недельных когортах видно то же самое: общая линия проваливается с конца июня, линия без paid_search идёт ровно.
Что сказать: «Retention не ухудшился: у прежних каналов он даже вырос. Общая цифра упала, потому что с июля почти треть новых пользователей приходит из платного поиска, а там возвращаются реже. Метрику стоит показывать по каналам, иначе каждое изменение микса будет выглядеть как проблема продукта».
Когорты по неделе регистрации, зрелые по D1. paid_search запущен 1 июля. Учебная база SQL-курса.
WITH d1 AS (
SELECT
u.user_id,
u.channel,
date_trunc('month', u.signup_date) AS cohort_month,
max(CASE
WHEN e.event_name = 'app_open'
AND CAST(e.event_time AS DATE) = u.signup_date + 1
THEN 1 ELSE 0
END) AS returned
FROM users u
LEFT JOIN events e ON e.user_id = u.user_id
WHERE u.signup_date <= DATE '2026-08-28'
GROUP BY u.user_id, u.channel, cohort_month
)
SELECT
cohort_month,
round(100.0 * sum(returned) / count(*), 2) AS d1_all,
round(100.0 * sum(returned) FILTER (WHERE channel <> 'paid_search')
/ count(*) FILTER (WHERE channel <> 'paid_search'), 2) AS d1_without_paid,
round(100.0 * count(*) FILTER (WHERE channel = 'paid_search') / count(*), 1) AS paid_share_pct
FROM d1
GROUP BY cohort_month
ORDER BY cohort_month;
-- июнь 57.01 | 57.01 | 0.0
-- июль 51.01 | 58.04 | 28.8
-- август 53.58 | 60.75 | 28.19. «Работает ли новый онбординг с чек-листом?»
Уточнение. Что считается успехом — метрика converted в таблице эксперимента, то есть достижение целевого действия. Перед сравнением групп проверяем, что сплит ровный, а после — смотрим главный сегмент: устройство.
Ответ. В контроле 1 527 человек, в варианте с чек-листом 1 541 — 49,8% на 50,2%, перекоса нет. В целом конверсия выросла с 20,0% до 30,3%. Но на десктопе она выросла с 20,0% до 39,8%, а на мобильных не изменилась: 20,1% и 19,9%. z-статистика для десктопа — около 8,6, для мобильных — около нуля. Весь общий прирост сделан десктопом.
Что сказать: «Чек-лист работает на десктопе — конверсия там выросла вдвое, и это не случайность. На мобильных эффекта нет. Предлагаю включить чек-лист на десктопе и отдельно разобраться, почему на телефоне он не помогает: возможно, его просто неудобно проходить». Раскатить на всех по общему приросту в 10,3 пункта было бы ошибкой: половина пользователей его не получит.
| Устройство | Контроль | Чек-лист | Разница |
|---|---|---|---|
| десктоп | 20,0% из 789 | 39,8% из 807 | +19,8 п.п. |
| мобильные | 20,1% из 738 | 19,9% из 734 | −0,2 п.п. |
| все | 20,0% из 1 527 | 30,3% из 1 541 | +10,3 п.п. |
SELECT
u.device,
x.variant,
count(*) AS users,
round(100.0 * avg(CASE WHEN x.converted THEN 1 ELSE 0 END), 1) AS conv_pct
FROM experiment_exposures x
JOIN users u ON u.user_id = x.user_id
GROUP BY u.device, x.variant
ORDER BY u.device, x.variant;
-- desktop: checklist 807 / 39.8, control 789 / 20.0
-- mobile: checklist 734 / 19.9, control 738 / 20.110. «Сколько мы зарабатываем в месяц на подписке?»
Уточнение. Какие подписки считать: только активные или ещё и те, у кого проблема с оплатой? В таблице подписок три статуса: active, past_due и churned. От выбора зависит ответ, поэтому определение надо назвать вместе с числом.
Ответ. Активных подписок 515, они дают $12 595 в месяц. С учётом 228 подписок в статусе past_due — $18 227. Подписки churned ($4 101) в MRR не входят. Второе число больше первого на 45%, и выбор между ними — не техническое, а финансовое решение.
Что сказать: «MRR по активным подпискам — $12 595. Если считать и тех, у кого просрочен платёж, — $18 227. Для отчёта предлагаю первое число и отдельной строкой — сумму под риском».
SELECT
status,
count(*) AS subscriptions,
sum(monthly_price) AS monthly_revenue
FROM subscriptions
GROUP BY status
ORDER BY status;
-- active 515 | 12595
-- churned 169 | 4101
-- past_due 228 | 563211. «Сколько клиентов уходит?»
Уточнение. Что значит «ушёл» и как выставляется статус? Это вопрос к владельцу таблицы, и его стоит задать до расчёта. Простой ответ — доля подписок в статусе churned: 169 из 912, 18,5%.
Ответ. Разбивка по месяцу начала подписки показывает странное: из июньских подписок ушли 2,4%, из июльских — 8,4%, из августовских — 33,4%, то есть 137 из 410. Но продление приходит через 30 дней после первого платежа, то есть у августовских подписок не раньше 31 августа — за границей выгрузки. Ни одна из них ещё не продлевалась. Значит, статус churned здесь означает не «не заплатил за следующий месяц», а что-то другое. Похоже на активность: у ушедших в среднем 3,3 дня с заходами в продукт, у активных — 9,4.
Что сказать: «Формально ушли 18,5% подписчиков. Но у августовских подписок статус выставлен до первой даты продления, так что это не отток в финансовом смысле, а скорее признак низкой активности. Прежде чем показывать эту цифру как churn, уточню правило статуса. Реальный отток по неоплате можно будет посчитать по платежам, когда наступят даты продления».
SELECT
date_trunc('month', started_at) AS start_month,
count(*) AS subscriptions,
count(*) FILTER (WHERE status = 'churned') AS churned,
round(100.0 * count(*) FILTER (WHERE status = 'churned') / count(*), 1) AS churn_pct
FROM subscriptions
GROUP BY start_month
ORDER BY start_month;
-- июнь 167 | 4 | 2.4
-- июль 335 | 28 | 8.4
-- август 410 | 137 | 33.412. «Можно отправлять отчёт руководству?»
Уточнение. Этот вопрос редко задают вслух, но аналитик задаёт его себе перед каждой отправкой. Проверка — не ритуал, а короткий список фактов о данных, которые могут изменить выводы.
Ответ. Для этой базы список такой. user_id в пользователях уникален. У 55 человек не указана страна — любые разрезы по странам должны это оговаривать. paid_search появляется только с 1 июля, поэтому его нельзя сравнивать с другими каналами «за всё время». Платежей без пользователя и платежей раньше регистрации нет. Последнее событие — 30 августа в 12:59, то есть последний день неполный.
Что сказать себе: каждое число в отчёте должно пережить эти оговорки. Сравнение каналов — на одинаковом периоде, retention — на зрелых когортах, DAU — без неполного дня, разрезы по странам — с отдельной строкой «не указана».
SELECT
(SELECT count(*) - count(DISTINCT user_id) FROM users) AS duplicate_user_ids,
(SELECT count(*) FROM users WHERE country IS NULL) AS users_without_country,
(SELECT min(signup_date) FROM users WHERE channel = 'paid_search') AS paid_search_first_day,
(SELECT count(*) FROM payments p
WHERE NOT EXISTS (SELECT 1 FROM users u WHERE u.user_id = p.user_id)) AS orphan_payments,
(SELECT count(*) FROM payments p JOIN users u ON u.user_id = p.user_id
WHERE p.paid_at < u.signup_date) AS paid_before_signup,
(SELECT max(event_time) FROM events) AS last_event;
-- 0 | 55 | 2026-07-01 | 0 | 0 | 2026-08-30 12:59:00Какие навыки нужны под эти задачи
Если разложить 12 вопросов на навыки, SQL окажется необходимым, но не главным. Все запросы выше — это GROUP BY, JOIN, условные агрегаты, пара подзапросов и даты. Это базовый уровень SQL, а не продвинутый. Выводы в половине вопросов изменились не из-за сложного запроса, а из-за уточнения: неполный день, недельный цикл, смена состава, правило статуса.
Поэтому на собеседованиях аналитика данных задачи часто звучат так же, как здесь: словами менеджера, без таблиц. Проверяют, спросите ли вы, что считать, и заметите ли подвох в данных. SQL-задачи на тех же таблицах, но в учебном формате, собраны в отдельном задачнике.
| Навык | Вопросы | Что именно |
|---|---|---|
| SQL: GROUP BY, JOIN, FILTER | все | посчитать людей, а не строки; не размножить строки |
| даты и окна наблюдения | 1, 3, 7, 8, 11 | неполный день, зрелые когорты, дата продления |
| сегментация | 5, 6, 7, 8, 9 | разрез по каналу или устройству меняет вывод |
| метрики продукта | 1, 5, 6, 7, 10 | DAU, ARPU, воронка, retention, MRR — с определением |
| эксперименты | 9 | проверка сплита, сегмент, решение по эффекту |
| разговор с заказчиком | все | уточнить вопрос и ответить в двух фразах |
Как потренироваться на этих задачах
Откройте песочницу SQL-курса и попробуйте ответить на каждый вопрос сами, не глядя в запросы выше. Главное упражнение — не синтаксис, а первые две минуты: записать, что вы уточнили бы у автора вопроса, и только потом писать запрос. Затем сверьте число и сравните свой ответ в чат с нашим.
В SQL-курсе этот путь пройден по шагам: главы 6–9 — DAU, активация, воронка и retention, глава 13 — самостоятельный кейс про бюджет paid_search, глава 16 — когорты, глава 17 — A/B-тест, где среднее скрывает сегмент. Первые главы открыты бесплатно.
Материалы по теме
Собеседование продуктового аналитика: метрики и кейсы с разбором
Как отвечать на продуктовые кейсы на собеседовании: падение DAU, воронка, retention, A/B-тест, новая функция и метрики, которые не стоит придумывать на ходу.
Собеседование аналитика данных: 30 задач и как решать их вслух
Большой практический гайд по собеседованию аналитика данных: SQL, Python, метрики, статистика, кейсы, дашборды и ответы, которые показывают ход мышления.
Учебная база данных для SQL: пример базы продукта на 45 185 строк
Учебная база данных для практики SQL: пять таблиц SaaS-продукта, связи, словарь колонок, первые запросы с результатами, A/B-тест внутри и честный список того, чего в ней нет.