В каком порядке выполняются SQL-операторы в запросе?
Что проверяют
Знаете ли вы логический порядок обработки запроса и умеете ли выводить из него следствия: почему алиас не виден в WHERE и почему оконную функцию нельзя фильтровать напрямую. Следом часто дают запрос с ошибкой и просят её найти.
Как отвечать
Логический порядок:
FROMиJOIN: собирается исходный набор строк, условияONприменяются при соединении;WHERE: фильтр отдельных строк, агрегатов ещё нет;GROUP BY: строки сворачиваются в группы, считаются агрегаты;HAVING: фильтр по группам, напримерHAVING count(*) > 5;- оконные функции: считаются после группировки и видят уже сгруппированный результат;
SELECT: вычисляются выражения, назначаются алиасы;DISTINCT: удаляются дубли;ORDER BY: сортировка, алиасы изSELECTздесь уже доступны;LIMITиOFFSET: отсечение строк.
Следствия стоит проговорить. Алиас из SELECT в WHERE недоступен, условие переписывают выражением или выносят запрос в CTE. PostgreSQL и MySQL разрешают алиас в GROUP BY, но это расширение, а не стандарт; ClickHouse пускает алиасы почти везде, и привычка оттуда ломает запросы в других базах. Чтобы оставить одну строку на группу через row_number(), запрос оборачивают в подзапрос, а в Snowflake, BigQuery и DuckDB есть QUALIFY.
Подчеркните, что порядок логический, а не физический. Оптимизатор проталкивает фильтры вниз, переставляет соединения, берёт индекс под ORDER BY ... LIMIT. Реальный план показывает EXPLAIN, в PostgreSQL с фактическим временем EXPLAIN ANALYZE.
Где спотыкаются
Называют порядок написания: SELECT, FROM, WHERE. Это синтаксис, а не обработка.
Пишут условие на правую таблицу LEFT JOIN в WHERE. Строки без пары получают NULL, фильтр их отбрасывает, и соединение молча становится внутренним. Такому условию место в ON.
Путают WHERE и HAVING: фильтруют агрегат в WHERE и получают ошибку или ставят в HAVING обычное условие по строкам, заставляя базу группировать лишнее.