Можно ли использовать псевдонимы в SQL после GROUP BY?
Что проверяют
Знаете ли вы логический порядок выполнения запроса и отличаете ли стандарт SQL от поведения конкретной СУБД. Следом обычно просят объяснить, почему алиас не работает в WHERE, и показать, как та же группировка выглядит в ORM, с которой вы работаете в Python.
Как отвечать
Начните с порядка: FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY. Алиасы появляются только на шаге SELECT, поэтому по стандарту ссылаться на них можно лишь в ORDER BY. Дальше разведите диалекты, потому что на практике всё зависит от базы:
- PostgreSQL: разрешает алиас и номер колонки в
GROUP BY(GROUP BY deptилиGROUP BY 1), но не вHAVINGи не вWHERE; - MySQL: пускает алиасы в
GROUP BYи вHAVING, но не вWHERE; - SQLite: самый либеральный, понимает алиас даже в
WHERE; - SQL Server: не пускает ни в
GROUP BY, ни вHAVING, выражение приходится повторять.
Переносимых способов два: повторить выражение (GROUP BY department, HAVING COUNT(*) > 10) или вынести расчёт в подзапрос или CTE, тогда алиас становится обычной колонкой для внешнего запроса.
Про Python: в Django values('department').annotate(cnt=Count('id')).filter(cnt__gt=10) превращается в GROUP BY и HAVING COUNT(...) > 10 с повтором выражения, ORM сама обходит ограничение. В SQLAlchemy в group_by() и having() надёжнее передавать само выражение, а не имя метки из label(): так запрос одинаково отработает на любой базе.
Где спотыкаются
Отвечают «нельзя, потому что GROUP BY выполняется раньше SELECT» и на этом останавливаются. Для стандарта это верно, но на PostgreSQL интервьюер покажет работающий GROUP BY dept, и ответ без оговорки про диалекты рассыпается.
Уверенно пишут алиас в HAVING, потому что так работало в MySQL. В PostgreSQL это ошибка column "emp_count" does not exist.
Не знают про конфликт имён. В PostgreSQL SELECT upper(name) AS name ... GROUP BY name сгруппирует по исходной колонке таблицы, а не по выражению: «Ivan» и «IVAN» окажутся в разных группах, и результат молча будет другим.