ССобесов
08 июня 2026 г.

Подготовка к SQL-секции собеса аналитика: 30 типов задач в 2026

Полный гид по SQL-собесу аналитика: JOIN, оконные функции, gaps-and-islands, когортная ретенция, sessionization, pivot, рекурсивный CTE. С задачами для тренировки.

SQL на собесе аналитика — почему именно эта секция самая важная

Если в 2026 году вы готовитесь к интервью на позицию аналитика, бизнес-аналитика, дата-аналитика или продуктового аналитика — SQL будет на 90% собесов. И эта секция чаще всего топит сильных кандидатов: математика лёгкая, кейс пройден, а простой запрос с окном не сошёлся, и всё.

В этом гиде разберём 30 типов задач, которые реально дают на собесах:

  • базовые SELECT-агрегации;
  • JOIN-ы во всех вариациях;
  • оконные функции;
  • gaps-and-islands;
  • когортную ретенцию;
  • sessionization;
  • pivot и unpivot;
  • рекурсивные CTE.

К каждому типу — пример задачи из нашего каталога, чтобы можно было пойти и сразу прорешать.

Базовые типы задач (1–5): фундамент

1. Агрегация и GROUP BY с фильтром

Самая простая задача, на которой умудряются ошибаться: «посчитать средний чек по категориям, где более 10 заказов». Подвох — фильтр должен быть в HAVING, а не в WHERE.

Тренировка: Habr · WHERE vs HAVING.

2. Вторая по величине зарплата

Классика всех собесов. Спросят почти везде, потому что задача проверяет, знаете ли вы оконные функции (DENSE_RANK) или умеете обходиться без них.

Тренировка: Habr · Вторая по зарплате и SQL · Вторая зарплата.

3. Удаление дубликатов

В чём разница между DISTINCT, GROUP BY, и оконной функцией ROW_NUMBER() OVER (PARTITION BY ...)? Тренировка: Habr · Удаление дублирующих email.

4. Процент от общего

«Посчитать долю каждой категории в общей выручке». Тренировка: Habr · Процент от общего.

5. Top-N в группе

«Топ-3 продукта в каждой категории». Решается через ROW_NUMBER или DENSE_RANK в PARTITION BY. Тренировка: Habr · Top-3 магазина по городу.

JOIN-ы (6–10): где сыпется большинство

6. INNER vs LEFT JOIN

Понимание: после LEFT JOIN с фильтром в WHERE поведение меняется. Если фильтр должен срабатывать «не нашли — пропустили строку», он в ON, а не в WHERE.

7. Self-join

«Найти сотрудников, которые получают больше своего менеджера». Self-join по таблице на саму себя — мастхэв. Тренировка: Habr · Self-join менеджеров.

8. Anti-join (NOT IN / NOT EXISTS)

«Клиенты без заказов». Должны помнить про ловушку: NOT IN с NULL вернёт пустой результат. Тренировка: Habr · Пользователи без заказов.

9. Cross join и его контролируемое использование

«Сгенерировать сетку дат» — типичная задача, где cross join осознанно нужен. Тренировка: Habr · Заполнение разрывов по датам.

10. FULL OUTER JOIN

Реже, но бывает. Спросят «как объединить две таблицы, чтобы не потерять записи ни в одной». Должны помнить про COALESCE для null-ов.

Оконные функции (11–18): сердцевина middle-задач

11. ROW_NUMBER, RANK, DENSE_RANK

Базовая трилогия. Должны помнить разницу: ROW_NUMBER всегда уникален, RANK оставляет «дырки», DENSE_RANK не оставляет.

12. LAG и LEAD

«Разница между текущим и предыдущим заказом пользователя». Тренировка: Awesome SQL · Скользящее окно % изменений.

13. Cumulative sum (SUM OVER)

Кумулятивная сумма по пользователю или по дате. Тренировка: SQL · Running total по пользователю, Awesome SQL · Running total, Habr · Running monthly sales.

14. Скользящее среднее (Rolling)

7-дневный moving average — must-have для аналитика. Тренировка: LeetCode · Restaurant growth 7-day MA.

15. NTH-row внутри окна

«Третья по дате покупка пользователя». Тренировка: Awesome SQL · Nth row.

16. Медиана с окном

В Postgres есть PERCENTILE_CONT. На MySQL — танец с подзапросами. Тренировка: Awesome SQL · Median, Habr · Median by group.

17. First/Last value в окне

FIRST_VALUE и LAST_VALUE с правильным фреймом. Подвох — без ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING LAST_VALUE ведёт себя не так, как ждёшь.

18. Doable: первая покупка пользователя

«Первая транзакция каждого клиента». Тренировка: Habr · Первая покупка пользователя.

Продвинутые задачи (19–25)

19. Gaps-and-islands: последовательные дни

«Найти максимальную серию подряд активных дней пользователя». Хитрый трюк: вычесть ROW_NUMBER из даты — получится постоянная для группы подряд идущих дней.

Тренировка: SQL · Consecutive streak, Awesome SQL · Consecutive logins, Habr · Consecutive days active.

20. Заполнение пропусков по датам

«Доход по дням, включая дни с нулевым доходом». Cross join + LEFT JOIN. Тренировка: Awesome SQL · Fill gaps.

21. Когортная ретенция

Самая частая «сложная» задача собеса. «Какая доля пользователей, зарегистрированных в январе, оставалась активной через 1, 2, 3 месяца?» Тренировка: SQL · Когортная ретенция помесячно, Habr · Cohort retention.

22. RFM-сегментация

«Распределить клиентов по 3 квантилям Recency, Frequency, Monetary». Тренировка: SQL · RFM-сегментация.

23. Воронка по событиям

«Конверсия search → product → cart → checkout → order». Тренировка: SQL · Воронка заказов по дням, Habr · Воронка конверсии.

24. Sessionization

«Сгруппировать события в сессии — если между событиями прошло > 30 минут, начинается новая сессия». Решается через LAG + накопительная сумма флага.

25. Pivot и unpivot

«Месячные продажи по категориям — каждый месяц колонкой». Тренировка: Habr · Pivot monthly, Awesome SQL · Pivot monthly.

Сложные паттерны (26–30): сеньорный уровень

26. Рекурсивный CTE

«Иерархия сотрудников — кто чей менеджер сверху до самого CEO». Рекурсивный CTE даёт обход дерева. Каждый второй senior-собес содержит такую задачу.

27. Stadium traffic (3+ дня подряд)

Классическая LeetCode-задача. «Найти 3+ дня подряд, где число посетителей > 100». Решается через окно и self-join.

Тренировка: LeetCode · Human traffic stadium.

28. Slowly Changing Dimensions (SCD type 2)

«Цена товара менялась — найти актуальную на момент заказа». Тренировка: SQL · Актуальные цены.

29. Воронка с правильной обработкой повторных событий

Простая воронка проваливается, если пользователь сделал кнопку «обновить» 3 раза. Нужно правильно дедуплицировать, не теряя последовательность.

30. EXISTS vs IN vs JOIN

Производительность одинаковых задач, реализованных по-разному. На сеньорном собесе про это могут спросить — особенно если у компании Postgres или ClickHouse.

Чек-лист подготовки к SQL-собесу

За 4 недели

  • Неделя 1: базовые SELECT, JOIN, GROUP BY. Прорешать 20 задач.
  • Неделя 2: оконные функции. Прорешать 25 задач.
  • Неделя 3: gaps-and-islands, cohort, funnel. 20 задач.
  • Неделя 4: pivot, рекурсия, sessionization. 10 задач + mock на 60 минут.

За 1 неделю (срочно)

  • День 1–2: оконные функции (ROW_NUMBER, LAG/LEAD, SUM OVER).
  • День 3: cohort retention и funnel.
  • День 4: gaps-and-islands.
  • День 5: pivot.
  • День 6: mock-интервью.
  • День 7: разбор ошибок и повтор.

За 1 день (катастрофа)

  • Перечитать синтаксис оконных функций.
  • Прорешать 5 ключевых задач (вторая зарплата, ретенция, воронка, running total, gaps-and-islands).
  • Не учить новое — повторить старое.

Топ-10 «инсайтов» SQL-собесов

  1. WHERE применяется до GROUP BY, HAVING — после. Это любимый теоретический вопрос.
  2. NOT IN с NULL возвращает пустой результат. Используйте NOT EXISTS.
  3. LEFT JOIN + WHERE превращается в INNER JOIN. Если хотите сохранить null — фильтр в ON.
  4. COUNT(*) считает строки, COUNT(колонка) пропускает null. Подвох на сравнении.
  5. SUM(x) OVER (ORDER BY date) по умолчанию накопительная. Полезно знать.
  6. DISTINCT — не функция, это модификатор SELECT. COUNT(DISTINCT x) работает, а DISTINCT x без SELECT — нет.
  7. ROW_NUMBER гарантированно уникален, RANK оставляет дырки. Помнить разницу.
  8. CTE — это не подзапрос, у него своя оптимизация. На Postgres до 12 — материализованный, после — opt-in.
  9. PARTITION BY без ORDER BY даёт окно без порядка. Cumulative sum работать не будет.
  10. HAVING без GROUP BY тоже работает. Применяется к одной «глобальной» группе.

Какие книги/материалы помогают

  1. «SQL за 10 минут» Бен Форта — базовый учебник.
  2. «SQL Pocket Guide» O'Reilly — справочник.
  3. «SQL Antipatterns» Bill Karwin — что НЕ надо делать.
  4. «Карьера аналитика» Karpov.Courses — практика на реальных задачах.
  5. LeetCode SQL 50 — для базовой механики.
  6. StrataScratch — продуктовые SQL-задачи.

Типичные ошибки на SQL-собесе

  1. Пишут без таймера. На реальном собесе на задачу обычно 10–15 минут.
  2. Не уточняют схему таблиц. «Какие колонки в orders?» — нормальный вопрос.
  3. Пишут «оптимально», ломая корректность. Сначала рабочий запрос, потом оптимизация.
  4. Заучивают шаблоны. Шаблон работает, пока задача типовая. Учитесь рассуждать с нуля.
  5. Не проверяют запрос. «А что если table A пустая?» — спросите себя сами.

Связанные задачи каталога

Для тренировки соберите такой пул из 25 задач:

Итого

SQL — это самая «механическая» секция собеса, но именно из-за этого проще всего готовиться. План: 60 задач за 4 недели, mock-интервью каждый weekend, ежедневная практика по 30 минут. К концу подготовки у вас в голове должна быть карта: «вижу задачу — знаю, оконку или CTE; вижу даты — думаю про gaps-and-islands». Когда эта карта появилась — SQL-секцию вы пройдёте.

Связанные задачи

Другие статьи