Общие табличные выражения
SELECT-запроса, где допускается табличное выражение.
На именованные подзапросы можно ссылаться по имени в области видимости текущего запроса или в областях видимости дочерних подзапросов.
Каждая ссылка на общее табличное выражение в SELECT-запросах всегда заменяется подзапросом из его определения, если CTE явно не определено как материализованное (см. Материализованные общие табличные выражения).
Рекурсия предотвращается за счёт исключения текущего CTE из процесса разрешения идентификаторов.
Обратите внимание, что CTE не гарантируют одинаковые результаты во всех местах, где к ним обращаются, поскольку для каждого случая использования запрос выполняется заново.
Синтаксис
Пример
1000000
Однако поскольку мы дважды обращаемся к cte_numbers, случайные числа каждый раз генерируются заново, и поэтому мы видим разные случайные результаты: 280501, 392454, 261636, 196227 и так далее…
Материализованные общие табличные выражения
MATERIALIZED указывает ClickHouse выполнить подзапрос CTE ровно один раз, сохранить результат во временной таблице и использовать эту таблицу для всех ссылок.
Это особенно полезно, когда один и тот же CTE используется в запросе несколько раз (например, в self-join’ах или нескольких подзапросах IN), поскольку базовое вычисление выполняется только один раз.
Материализованные CTE — экспериментальная возможность.
Для их использования должны быть включены анализатор и настройка
enable_materialized_cte.Синтаксис
Когда использовать
- Один и тот же CTE используется в запросе более одного раза.
Без
MATERIALIZEDкаждая ссылка на него повторно выполняет подзапрос независимо. - CTE содержит недетерминированные функции, такие как
generateRandom. Материализация гарантирует, что все ссылки будут видеть одни и те же данные. - CTE включает ресурсоёмкие вычисления (агрегации, JOIN, сканирование больших объёмов данных), которые не следует выполнять повторно.
Примеры
MATERIALIZED обе стороны JOIN выполняли бы подзапрос независимо.
С MATERIALIZED таблица сканируется один раз, и обе стороны JOIN читают из одной и той же временной таблицы.
generateRandom дают разные результаты при каждом обращении.
Материализация CTE обеспечивает согласованность:
1000000.
Пример 3: Цепочка материализованных CTE
Материализованные CTE могут ссылаться на другие материализованные CTE.
ClickHouse определяет зависимости и материализует их в правильном порядке:
Ограничения
- Требуется экспериментальная настройка: настройка
enable_materialized_cteдолжна быть включена. - Требуется анализатор: материализованные CTE работают только при включенном анализаторе (
enable_analyzer = 1). - Не поддерживается с
RECURSIVE: использование ключевых словMATERIALIZEDиRECURSIVEвместе не допускается и приводит к исключениюUNSUPPORTED_METHOD. - Коррелированные CTE запрещены: материализованный CTE не может ссылаться на столбцы из внешних областей видимости запроса.
Общие скалярные выражения
WITH.
На общие скалярные выражения можно ссылаться в любом месте запроса.
Если общее скалярное выражение ссылается не на константный литерал, выражение может приводить к появлению свободных переменных.
ClickHouse разрешает любой идентификатор в ближайшей возможной области видимости, а значит, при конфликтах имен свободные переменные могут ссылаться на неожиданные сущности или приводить к коррелированному подзапросу.
Рекомендуется определять CSE как лямбда-функцию (это возможно только при включенном анализаторе), связывая все используемые идентификаторы, чтобы добиться более предсказуемого разрешения идентификаторов в выражениях.
Синтаксис
Примеры
extension не привязана в теле лямбда-функции gen_name.
Хотя extension определена как '.txt' в виде общего скалярного выражения в области видимости определения и использования generated_names, она разрешается как столбец таблицы extension_list, поскольку доступна в подзапросе generated_names.
Рекурсивные запросы
RECURSIVE позволяет запросу WITH обращаться к собственному результату. Пример:
Пример: Суммирование целых чисел от 1 до 100
Рекурсивные CTE опираются на анализатор запросов, добавленный в версии
24.3. Если вы используете версию 24.3+ и сталкиваетесь с исключением (UNKNOWN_TABLE) или (UNSUPPORTED_METHOD), это означает, что анализатор отключен для вашего экземпляра, роли или профиля. Чтобы включить анализатор, активируйте настройку allow_experimental_analyzer или обновите настройку compatibility до более новой версии.
Начиная с версии 24.8, анализатор был полностью переведен в промышленную эксплуатацию, а настройка allow_experimental_analyzer была переименована в enable_analyzer.WITH всегда состоит из нерекурсивного выражения, затем UNION ALL, затем рекурсивного выражения, при этом только рекурсивное выражение может содержать ссылку на собственный результат запроса. Рекурсивный CTE-запрос выполняется следующим образом:
- Вычислите нерекурсивное выражение. Поместите результат запроса нерекурсивного выражения во временную рабочую таблицу.
- Пока рабочая таблица не пуста, повторяйте следующие шаги:
- Вычислите рекурсивное выражение, подставив текущее содержимое рабочей таблицы вместо рекурсивной самоссылки. Поместите результат запроса рекурсивного выражения во временную промежуточную таблицу.
- Замените содержимое рабочей таблицы содержимым промежуточной таблицы, затем очистите промежуточную таблицу.
Порядок обхода
Обнаружение циклов
Maximum recursive CTE evaluation depth:
Бесконечные запросы
LIMIT:
Пример: Бесконечный рекурсивный CTE-запрос
Завершающая запятая
WITH: