SQL для аналитика: практика на задачах
SQL для аналитика нужен для получения данных, расчёта метрик и проверки аналитических гипотез запросами. Базовая практика включает фильтрацию, JOIN, группировки, агрегаты, оконные функции и работу с датами.
Обновлено · Команда SQL Arena
Что потренируете
- Агрегации и GROUP BY для продуктовых метрик
- JOIN между событиями, пользователями и сущностями продукта
- Работа с датами, периодами и когортами
- Оконные функции для ранжирования и последовательностей
- Проверка логики воронок, retention и конверсии
Пример задачи в тренажёре
Так выглядит задача в SQL Arena: условие, редактор, результат и схема базы.
Есть таблица продуктов и журнал событий пользователей. Для каждого продукта посчитайте число уникальных пользователей, у которых есть хотя бы одно событие. Верните только продукты минимум с двумя активными пользователями. В результате нужны колонки product_name и active_users. Отсортируйте сначала по числу пользователей по убыванию, затем по названию продукта.
SELECT p.product_name, COUNT(DISTINCT e.user_name) AS active_users FROM products p JOIN user_events e ON e.product_id = p.id GROUP BY p.id, p.product_name HAVING COUNT(DISTINCT e.user_name) >= 2 ORDER BY active_users DESC, p.product_name;
| # | product_name | active_users |
|---|---|---|
| 1 | Ledger | 4 |
| 2 | Pulse | 3 |
| 3 | Canvas | 2 |
Есть таблица продуктов и журнал событий пользователей. Для каждого продукта посчитайте число уникальных пользователей, у которых есть хотя бы одно событие. Верните только продукты минимум с двумя активными пользователями. В результате нужны колонки product_name и active_users. Отсортируйте сначала по числу пользователей по убыванию, затем по названию продукта.
SELECT p.product_name, COUNT(DISTINCT e.user_name) AS active_users FROM products p JOIN user_events e ON e.product_id = p.id GROUP BY p.id, p.product_name HAVING COUNT(DISTINCT e.user_name) >= 2 ORDER BY active_users DESC, p.product_name;
Разбор SQL-запроса для аналитика
Начинаем с связи двух таблиц. В products хранится одна строка на продукт, а в user_events может быть много событий одного продукта. Поэтому JOIN user_events e ON e.product_id = p.id превращает каждый продукт в набор связанных событий. Для аналитика это базовый шаблон: справочник сущностей соединяется с таблицей фактов, после чего факты агрегируются.
Дальше запрос группирует строки по продукту. Важно использовать COUNT(DISTINCT e.user_name), а не обычный COUNT(*). Если Anna откроет один и тот же продукт пять раз, пять событий не должны превращаться в пять активных пользователей. DISTINCT меняет единицу измерения: мы считаем людей, а не строки событий. Именно такие различия постоянно возникают при расчёте DAU, охвата, числа покупателей и других метрик.
HAVING применяется уже после группировки и оставляет продукты, у которых получилось минимум два уникальных пользователя. WHERE здесь не заменит HAVING, потому что условие зависит от результата агрегатной функции. Последний ORDER BY задаёт однозначный порядок: сначала продукты с большей аудиторией, а при равенстве — по названию. Это полезно не только для примера: стабильная сортировка делает отчёты и проверки результатов воспроизводимыми.
SQL для аналитика данных обычно строится вокруг нескольких повторяющихся операций: выбрать нужный срез, соединить факты со справочниками, сгруппировать строки и посчитать метрики. Важно понимать разницу между COUNT(*) и COUNT(DISTINCT ...), правильно выбирать тип JOIN и следить за уровнем детализации результата. Следующий уровень — оконные функции, CTE и работа с датами: они помогают считать рейтинги, накопительные значения, интервалы между событиями и метрики по периодам без множества промежуточных запросов.
SELECT p.product_name, COUNT(DISTINCT e.user_name) AS active_users FROM products p JOIN user_events e ON e.product_id = p.id GROUP BY p.id, p.product_name HAVING COUNT(DISTINCT e.user_name) >= 2 ORDER BY active_users DESC, p.product_name;
| product_name | active_users |
|---|---|
| Ledger | 4 |
| Pulse | 3 |
| Canvas | 2 |
Типичные ошибки аналитиков в SQL
Считать события вместо пользователей
Если написать COUNT(*), запрос покажет число строк в журнале событий. Пользователь с несколькими событиями будет учтён несколько раз, поэтому метрика активной аудитории окажется завышенной. Для количества уникальных пользователей здесь нужен COUNT(DISTINCT user_name).
Фильтровать агрегат через WHERE
Условие WHERE COUNT(...) >= 2 в таком запросе не работает, потому что WHERE применяется до группировки. Условия на итоговые агрегаты задаются через HAVING. Это особенно важно при задачах на выручку по группам, число заказов и средние значения.
Забыть о гранулярности данных
После JOIN одна строка продукта превращается в несколько строк событий. Если затем добавить в SELECT колонку, которая не входит в группировку и не агрегируется, логика запроса развалится. Перед написанием SQL полезно сформулировать, чему соответствует одна строка результата.
Задачи по теме в тренажёре
Трек «SQL с нуля → Аналитик»В SQL Arena можно продолжить на задачах, где аналитическая логика постепенно становится сложнее. На Easy встречаются выбор последнего платежа, поиск всех платежей заказа и определение магазинов, где продавался товар. Дальше появляются задачи на распределения, CTR и порядковый номер транзакции пользователя. Такие упражнения заставляют не просто вспомнить оператор, а выбрать правильную гранулярность, соединение и способ агрегации. Для системной практики есть трек «SQL с нуля → Аналитик» из 63 задач. Он подходит как следующий шаг после базового SELECT и ведёт к типичным аналитическим конструкциям. В SQL Arena всего 1 192 задачи, поэтому у задач разные таблицы и данные, а не один учебный набор. Решение проверяется на скрытых данных: запрос должен работать по смыслу, а не только выдавать нужные строки на примере. Отдельно можно практиковаться в PostgreSQL, MySQL, ClickHouse и BigQuery прямо в браузере. Для разбора сложных запросов доступны EXPLAIN и ER-диаграммы, а AI-ментор может объяснить ошибку или дать подсказку. Есть и режим «Собеседование» с серверным таймером и отчётом после сессии.
- EasyбесплатноПоследние платежиpostgresql
- EasyбесплатноВсе платежи заказаpostgresql
- EasyбесплатноГде продавался этот товарpostgresql
- EasyбесплатноПовторяющиеся вакансииpostgresqlmysqlclickhouse
- MediumPremiumРаспределение пользователей по количеству твитовpostgresqlmysqlclickhouse
- MediumPremiumCTR приложений за 2022 годpostgresqlmysqlclickhouse
- MediumPremiumТретья транзакция каждого пользователяpostgresqlmysqlclickhouse
- MediumPremiumВремя на отправку и просмотр снаповpostgresqlmysqlclickhouse
Справочник по теме
Подробные статьи с синтаксисом и примерами в справочнике SQL Arena.
Частые вопросы
Какой SQL нужен аналитику?
Аналитику прежде всего нужны SELECT, WHERE, GROUP BY, агрегатные функции, JOIN, подзапросы, CTE и оконные функции. Также важно уверенно работать с датами, NULL и условной логикой через CASE.
Чем SQL для аналитиков отличается от обычного SQL?
Сам язык тот же, но акцент обычно делается на чтении и преобразовании данных для анализа. Аналитик чаще считает метрики, объединяет фактовые и справочные таблицы, строит срезы и проверяет качество результата.
Что должен знать SQL аналитик данных?
Нужно понимать фильтрацию, группировку, JOIN, агрегаты, оконные функции и CTE. Не менее важно уметь замечать дубли после соединений, правильно считать уникальные сущности и проверять гранулярность итоговой таблицы.
Какие SQL тренажёры подходят для аналитиков?
Полезнее всего тренажёр, где приходится самостоятельно писать запрос, а не выбирать ответ из готовых вариантов. Задачи должны охватывать соединения таблиц, агрегации, метрики, окна и другие типичные аналитические операции.
Практика SQL для аналитиков на задачах
Откройте трек «SQL с нуля → Аналитик»: в нём 63 задачи, которые ведут от базовых запросов к более характерным для аналитика агрегациям, датам и оконным функциям.
Открыть трек для аналитика