SQL — первый навык, который спрашивают у Junior аналитика данных. Неважно, работаете ли вы в продукте, маркетинге или финансах — если у компании есть база данных, вам нужен SQL. Вот честный roadmap без лишней воды.
Уровень 1: Базовый SQL (1-2 недели)
Это то, что нужно знать назубок:
SELECT, WHERE, ORDER BY, LIMIT
-- Получить 10 самых дорогих товаров категории «Электроника»
SELECT id, name, price
FROM products
WHERE category = 'Электроника' AND is_active = true
ORDER BY price DESC
LIMIT 10;
Что нужно понять:
- Порядок выполнения SQL (FROM → WHERE → SELECT → ORDER → LIMIT)
- Операторы сравнения:
=,!=,>,<,BETWEEN,IN,LIKE - Логические операторы:
AND,OR,NOT - NULL:
IS NULL/IS NOT NULL
Агрегатные функции + GROUP BY
-- Выручка по категориям за последний месяц
SELECT
category,
COUNT(*) AS orders,
SUM(amount) AS revenue,
AVG(amount) AS avg_order
FROM orders
WHERE created_at >= NOW() - INTERVAL '30 days'
GROUP BY category
ORDER BY revenue DESC;
Что нужно понять:
COUNT(*)vsCOUNT(col)(NULL не считается)HAVING— фильтр после группировки- Разница
WHEREиHAVING
Уровень 2: JOIN и подзапросы (2-3 недели)
JOIN — самое важное
-- Заказы с именами пользователей
SELECT u.name, o.amount, o.created_at
FROM orders o
JOIN users u ON u.id = o.user_id
WHERE o.status = 'completed';
-- Пользователи без заказов (LEFT JOIN)
SELECT u.name, COUNT(o.id) AS orders
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id, u.name
HAVING COUNT(o.id) = 0;
Потратьте время на понимание разницы INNER / LEFT / FULL JOIN — это гарантированный вопрос на собеседовании.
Подзапросы
-- Пользователи с суммой покупок выше средней
SELECT user_id, SUM(amount) AS total
FROM orders
GROUP BY user_id
HAVING SUM(amount) > (SELECT AVG(total) FROM (
SELECT user_id, SUM(amount) AS total FROM orders GROUP BY user_id
) sub);
Уровень 3: Аналитический SQL (3-4 недели)
CTE (WITH)
WITH monthly_revenue AS (
SELECT
DATE_TRUNC('month', created_at) AS month,
SUM(amount) AS revenue
FROM orders WHERE status = 'completed'
GROUP BY 1
)
SELECT month, revenue,
LAG(revenue) OVER (ORDER BY month) AS prev_month,
ROUND((revenue - LAG(revenue) OVER (ORDER BY month))
/ LAG(revenue) OVER (ORDER BY month) * 100, 1) AS growth_pct
FROM monthly_revenue;
Оконные функции
Это то, что отличает Junior от Middle:
-- Ранг пользователей по выручке
SELECT
user_id,
total_spent,
RANK() OVER (ORDER BY total_spent DESC) AS rank,
ROUND(total_spent / SUM(total_spent) OVER () * 100, 1) AS pct_of_total
FROM user_totals;
Обязательно: ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, SUM OVER, AVG OVER.
Практические задачи (самые частые на собеседованиях)
1. Второй по величине
SELECT DISTINCT salary FROM employees ORDER BY salary DESC LIMIT 1 OFFSET 1;
-- Или через DENSE_RANK (лучше):
SELECT salary FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk FROM employees
) t WHERE rnk = 2;
2. Дубликаты
-- Найти email которые встречаются несколько раз
SELECT email, COUNT(*) AS cnt FROM users GROUP BY email HAVING COUNT(*) > 1;
3. Нарастающий итог
SELECT date, revenue, SUM(revenue) OVER (ORDER BY date) AS running_total
FROM daily_sales;
4. Топ N в каждой группе
-- Топ-3 товара по продажам в каждой категории
SELECT category, product_name, revenue
FROM (
SELECT category, product_name, revenue,
RANK() OVER (PARTITION BY category ORDER BY revenue DESC) AS rnk
FROM product_sales
) t
WHERE rnk <= 3;
5. Retention (возвращаемость)
-- Сколько пользователей вернулось через 7 дней
SELECT COUNT(DISTINCT a.user_id) AS returned
FROM user_events a
JOIN users u ON u.id = a.user_id
WHERE a.event_date = u.created_at::date + 7;
Что спрашивают на собеседованиях
| Тема | Частота |
|---|---|
| JOIN (INNER vs LEFT) | ⭐⭐⭐⭐⭐ |
| GROUP BY + HAVING | ⭐⭐⭐⭐⭐ |
| Второй/N-й по величине | ⭐⭐⭐⭐⭐ |
| Дубликаты | ⭐⭐⭐⭐ |
| ROW_NUMBER vs RANK | ⭐⭐⭐⭐ |
| CTE vs подзапрос | ⭐⭐⭐⭐ |
| NULL и COUNT(*) | ⭐⭐⭐⭐ |
| Нарастающий итог | ⭐⭐⭐ |
| Когортный анализ | ⭐⭐⭐ |
Рекомендуемый порядок обучения
Недели 1-2: SELECT, WHERE, ORDER, LIMIT, агрегаты, GROUP BY
- Ресурс: курс «SQL с нуля» на SQLab (наш курс бесплатный)
- Задачи: простые задачи на тренажёре
Недели 3-4: JOIN (все виды), подзапросы, EXISTS
- Ресурс: тренажёр с реальными датасетами
- Задачи: задачи уровня Medium
Недели 5-6: CTE, оконные функции, аналитика
- Ресурс: статьи блога + практика
- Задачи: задачи уровня Hard
Неделя 7-8: Подготовка к собеседованию
- Ресурс: раздел «Собесы» на SQLab (150+ вопросов)
- Практика: задачи в формате интервью
Что НЕ нужно на старте
- DDL (CREATE TABLE, ALTER) — изучите позже
- Хранимые процедуры — это администрирование, не аналитика
- Репликация, партиционирование — для DBA
- NoSQL — отдельная тема, после SQL
- Python/R — полезно, но вторично
Реальные инструменты
Знать SQL — недостаточно. Нужно знать инструменты:
- DBeaver — бесплатный GUI для PostgreSQL, MySQL, и всего остального
- DataGrip — платный, очень удобный (бесплатно для студентов)
- Metabase / Superset — для дашбордов без кода
- dbt — трансформация данных, SQL-проекты (изучите как Junior+)
Итог: 3 месяца до первой работы
| Месяц | Фокус | Результат |
|---|---|---|
| 1 | Базовый SQL + JOIN | Решаете простые задачи |
| 2 | Оконные функции + CTE | Можете анализировать данные |
| 3 | Практика + подготовка к интервью | Готовы к Junior-позиции |
Главное — практика на реальных данных, а не чтение. Порешайте 50-100 задач и вы будете в топе кандидатов на Junior аналитика.