SQL аналитик без этих 10 паттернов пишет запросы, которым нельзя доверять.

Типичная ситуация: на собесе “просто посчитайте ретеншн/воронку”, а в реальной работе “почему цифры не сходятся с дашбордом и вчерашним отчётом”. И проблема почти никогда не в “сложной математике”. Она в том, что SQL-логика не выдерживает грязные данные, дубли, пересечения периодов и взрывающиеся join’ы. Итог — неверные решения продукта, ссоры с BI и бесконечные пересчёты.

Механика ошибки простая: SQL честно делает то, что вы попросили. Если вы не задали порядок, уникальность, границы сессии и правила агрегации — получите случайный ответ, только красиво отформатированный.

Самопроверка: если вы уверенно делаете эти 10 вещей, вы “рабочий” аналитик, а не человек, который умеет SELECT.

  1. Оконные функции: ранжирование, last/first, лаги, доли от общего без лишних джойнов
  2. Дедуп: выбор “канонической” записи по правилу, а не DISTINCT на удачу
  3. Join-ловушки: 1 ко многим, many-to-many, дубли ключей, проверка кардинальности до агрегации
  4. Сессии: разбиение по таймауту/границам дня, сбор событий в сессию без двойного счёта
  5. Retention: когорта, окно наблюдения, правильная единица “возврата” и контроль повторных событий
  6. Воронки: порядок шагов, один пользователь — один шаг, что делать с пропусками и повторениями
  7. Анти-ошибки в агрегациях: где GROUP BY должен стоять до join’а, а где после
  8. Подзапросы и CTE: читаемость и контроль гранулярности, “одна CTE — одна ответственность”
  9. Проверки качества прямо в SQL: уникальность ключа, доля null, диапазоны дат, “не может быть больше 1”
  10. EXPLAIN-подход: понимать, где полный скан, где сортировка, где хеш-джойн, и почему запрос внезапно стал дорогим

В правильной практике запрос начинается не с “какие поля нужны”, а с “какая гранулярность таблицы на каждом шаге и где я фиксирую уникальность”. Обычно спорят про стиль CTE и “оптимизацию заранее”, но без этих паттернов спорить не о чем: вы просто не контролируете ответ. Граница применимости простая: если у вас один маленький датасет и один источник — многое прощается, но в проде с несколькими витринами эти ошибки вылезают сразу.