Можно ли использовать одинаковые алиасы в разных join?
Что проверяют
Понимаете ли вы область видимости алиасов в SQL. Правильный ответ короткий: в одном FROM нельзя, в разных подзапросах можно. Следом обычно спрашивают про самосоединение таблицы и про алиасы колонок.
Как отвечать
Разделите вопрос на уровни запроса:
- один уровень запроса: все таблицы в
FROMиJOINобразуют одну область видимости, и алиасы в ней обязаны быть уникальными.FROM orders o JOIN clients o ON ...упадёт с ошибкой: в PostgreSQL этоtable name "o" specified more than once, в MySQLNot unique table/alias, в SQL Server похожее сообщение про correlation name. Иначе СУБД не поняла бы, к какой таблице относитсяo.id; - одна таблица дважды: самосоединение или две роли одной сущности требуют разных алиасов, например
users AS authorиusers AS reviewer; - разные подзапросы и CTE: у каждого своя область видимости, и один и тот же алиас
oвнутри двух CTE или двух частейUNIONконфликта не создаёт; - вложенный подзапрос: внутренний алиас перекрывает внешний с тем же именем. В коррелированном подзапросе это опасно: неквалифицированная колонка, которой нет во внутренней таблице, молча возьмётся из внешней;
- алиасы колонок: одинаковые имена в
SELECTмногие СУБД допускают в итоговом результате, но уровнем выше, в CTE или подзапросе, обращение к такой колонке становится неоднозначным, аCREATE VIEWпросто откажется создаваться.
Практический вывод для аналитика: давайте алиасы по смыслу, квалифицируйте каждую колонку алиасом таблицы и не переиспользуйте одно имя даже там, где это разрешено. Отчёт потом будут читать другие люди.
Где спотыкаются
Утверждают, что СУБД разрешает повторять алиас в соседних JOIN и сама разберётся. Не разрешает, запрос не выполнится.
Не знают, что алиасы без кавычек нечувствительны к регистру: A и a для PostgreSQL одно и то же имя.
Пишут в подзапросе колонку без алиаса и получают коррелированный подзапрос вместо обычного. Классика: WHERE id IN (SELECT id FROM ...), где во внутренней таблице колонки id нет. Условие берёт id из внешней таблицы и становится истинным для всех строк, если подзапрос вообще что-то вернул.