Если у CTE задан явный список имён столбцов, не совпадающий с именами в его SELECT, какие имена увидит внешний запрос?
Внешний запрос увидит имена из явного списка столбцов CTE. Они заменяют имена, выведенные внутренним SELECT, но не меняют сами значения и порядок столбцов.
CTE появился как способ дать промежуточному результату запроса именованный интерфейс. Это упрощает чтение сложных запросов и позволяет явно отделить внутреннюю логику формирования набора данных от его использования.
Явный список имён дополнительно решает проблему нестабильных или невыразительных имён, возникающих из выражений, агрегатов и вычисляемых столбцов.
Если разработчик ожидает имена из внутреннего SELECT, но CTE переименовывает их своим списком, внешний запрос может обратиться не к тем именам или получить ошибку неизвестного столбца.
Количество имён в списке должно соответствовать количеству столбцов результата CTE. Список переименовывает столбцы по позиции, поэтому особенно важно не перепутать их порядок.
Имена столбцов CTE задаются на уровне его результирующего отношения. Внутренний SELECT сначала формирует столбцы и значения, после чего явный список присваивает им новые имена слева направо.
В этом примере внутреннее выражение COUNT(*) могло бы получить диалектное или автоматически сгенерированное имя, но внешний запрос использует имя order_count, заданное CTE.
Список имён не преобразует типы, не меняет порядок строк и не влияет на правила вычисления запроса. Он также не создаёт дополнительные столбцы: лишнее имя или нехватка имён приводят к ошибке в СУБД, поддерживающей такой синтаксис.
Практическое преимущество — стабильный контракт между CTE и внешней частью запроса. Это особенно полезно, когда внутренний SELECT изменяется: выражение можно заменить, сохранив понятное имя результата для потребителей CTE.
В отчёте CTE вычислял число обращений клиента. Сначала внутренний запрос возвращал столбец с понятным псевдонимом, но после рефакторинга псевдоним удалили, и разные СУБД начали по-разному формировать имя агрегата.
Рассматривались два варианта. Оставить имена на усмотрение СУБД было проще, но создавало риск несовместимости и ошибок при чтении запроса. Задать имена только через псевдонимы внутри SELECT было достаточно для текущей версии, но менее явно фиксировало интерфейс CTE.
Выбрали явный список имён CTE. Внешний запрос получил стабильные имена client_id и request_count, а внутреннюю реализацию можно менять без изменения обращений к CTE. Результатом стал более предсказуемый и переносимый запрос.
Нет. Он действует только на результирующие столбцы конкретного CTE. Имена столбцов исходных таблиц не изменяются, а при обращении к самой таблице используются её собственные имена.
Да, но переименование выполняется по позиции. Первое имя относится к первому столбцу результата SELECT, второе — ко второму и так далее. Поэтому изменение порядка списка может сделать запрос формально корректным, но логически ошибочным, особенно если столбцы имеют совместимые типы.
Нет. Он меняет только имя, под которым столбец доступен. Тип, значение и свойства выражения сохраняются, поэтому внешний запрос может сортировать, фильтровать или вычислять выражения на основе этого столбца обычным образом.