Продвинутый SQL: как выбрать курс после основ

Продвинутый SQL нужен, когда вы уже умеете писать SELECT, JOIN и GROUP BY, но сложный отчёт всё ещё собирается методом проб и ошибок. Следующая ступень — научиться переводить бизнес-правило в запрос и доказывать правильность результата на неудобных данных.

Если цель — подготовка к собеседованию аналитика, полезно тренировать эти же навыки: объяснять гранулярность, обработку NULL, одинаковых значений и пропущенных дат. Ниже — способ выбрать программу, короткий пример диагностики и подходящий маршрут на Latorn. Мы описываем собственный платный курс, а не независимый рейтинг школ.

После основ SQL есть разные направления

Ваша цельЧто должно быть в программе
Сложные аналитические запросыМногошаговые вычисления, окна, когорты, воронки, интервалы и сверка показателей
SQL-собеседованиеСамостоятельное решение новых задач и объяснение решений, включая крайние случаи
Производительность PostgreSQLПланы выполнения, индексы, статистика и особенности именно PostgreSQL
Администрирование баз данныхРезервное копирование, восстановление, доступы и эксплуатация

Курс сложных запросов не обязан быть курсом администрирования. А слово SQL не означает одинаковый диалект во всех упражнениях. До оплаты проверьте СУБД, в которой запускаются решения: функции дат, планы выполнения и некоторые конструкции отличаются.

Пример: JOIN работает, а сумма неверная

Пусть у заказа №1 сумма 300, а у заказа №2 — 500. В таблице позиций у первого заказа две строки, у второго — одна. После соединения таблицы заказов с позициями сумма из первой таблицы повторится дважды. Итого получится 1100 вместо 800.

WITH orders(order_id, amount) AS (
  VALUES (1, 300), (2, 500)
), items(order_id, sku) AS (
  VALUES (1, 'A'), (1, 'B'), (2, 'C')
)
SELECT SUM(o.amount) AS total
FROM orders o
JOIN items i ON i.order_id = o.order_id;

Пример проверен в SQLite. Проблема не в синтаксисе, а в том, что одна строка результата соединения означает позицию заказа, а сумма хранится на уровне заказа. Если задача — посчитать сумму заказов, имеющих хотя бы одну позицию, можно использовать EXISTS:

WITH orders(order_id, amount) AS (
  VALUES (1, 300), (2, 500)
), items(order_id, sku) AS (
  VALUES (1, 'A'), (1, 'B'), (2, 'C')
)
SELECT SUM(o.amount) AS total
FROM orders o
WHERE EXISTS (
  SELECT 1 FROM items i WHERE i.order_id = o.order_id
);

Теперь результат — 800. Но даже это исправление нужно соотнести с условием: должны ли учитываться заказы без позиций? Если да, фильтрация через EXISTS не подходит. Добавить DISTINCT к сумме — не универсальное решение: два разных заказа могут иметь одинаковую стоимость.

Как понять, чего вам не хватает

  1. Соединения и гранулярность. Можете заранее сказать, что означает строка результата и где возможны дубли? Начните с практики JOIN.
  2. Оконные функции. Понимаете разницу между выбором строки, ранжированием и накопительным вычислением? Можете объяснить поведение при равных значениях? Проверьте задачи на окна.
  3. Время и история. Отличаете семь наблюдений от семи календарных дней? Учитываете пропуски, границы периода и дату среза?
  4. Бизнес-метрики. Можете явно определить когорту, знаменатель retention и порядок событий в воронке до написания запроса?
  5. Проверка результата. Создаёте небольшой пример, на котором два правдоподобных запроса дают разные ответы?

Оконные функции сохраняют отдельные строки, в отличие от обычной агрегации по группам. Их рамки и порядок требуют внимания; примеры этих правил есть в документации PostgreSQL. При переносе решения из учебного тренажёра сверяйте детали со своей СУБД.

Когда достаточно бесплатных задач

Если пробел локальный — например, вы забыли LAG или путаете EXISTS, — начните с документации и узкой подборки. Если каждая новая многошаговая задача требует подсматривать готовое решение, полезнее последовательная программа с постепенным усложнением и проверкой запросов.

Для самопроверки есть подборка подготовки к SQL-собеседованию. Это учебные задания, а не обещание вопросов конкретной компании или успешного найма. После решения попробуйте объяснить запрос без редактора и изменить одно правило задачи: именно так обнаруживается, поняли ли вы приём.

Что предлагает платное продолжение

В курсе «Продвинутый SQL: сложные запросы и задачи для собеседований» разбираются размножение строк при JOIN, оконные рамки, календарные ряды, исторические значения, интервалы, когорты, последовательные воронки, рекурсивные CTE и сверка отчётов. Практика выполняется в SQLite; в программе есть работа с EXPLAIN QUERY PLAN именно этой СУБД.

Для старта нужны SELECT, WHERE, GROUP BY, HAVING, INNER/LEFT JOIN и знакомство с CTE и базовыми оконными функциями. Если это пока сложно, разумнее закончить основы. Если база уже есть, а требуется связная практика сложных запросов, откройте программу и пробные материалы курса и сравните их со своим списком пробелов.

Продолжить на практике