Pular para o conteúdo principal
O ClickHouse oferece suporte a expressões de tabela comuns (CTE), expressões escalares comuns e consultas recursivas.

Expressões de tabela comuns

As expressões de tabela comuns representam subconsultas nomeadas. Elas podem ser referenciadas pelo nome em qualquer consulta SELECT na qual uma expressão de tabela seja permitida. As subconsultas nomeadas podem ser referenciadas pelo nome no escopo da consulta atual ou nos escopos das subconsultas filhas. Toda referência a uma expressão de tabela comum em consultas SELECT é sempre substituída pela subconsulta definida em sua definição, caso a CTE não esteja explicitamente definida como materializada (consulte Expressões de tabela comuns materializadas). A recursão é evitada ocultando a CTE atual do processo de resolução de identificadores. Observe que as CTEs não garantem os mesmos resultados em todos os locais em que são chamadas, porque a consulta será executada novamente a cada uso.

Sintaxe

Exemplo

Um exemplo de quando uma subconsulta é reexecutada:
Se as CTEs retornassem exatamente os resultados, e não apenas um trecho de código, você sempre veria 1000000 No entanto, como estamos nos referindo a cte_numbers duas vezes, números aleatórios são gerados a cada vez e, consequentemente, vemos resultados aleatórios diferentes, 280501, 392454, 261636, 196227 e assim por diante…

Expressões de tabela comuns materializadas

Por padrão, o ClickHouse incorpora a subconsulta de uma CTE em cada referência, reexecutando-a todas as vezes. Adicionar a palavra-chave MATERIALIZED instrui o ClickHouse a executar a subconsulta da CTE exatamente uma vez, armazenar os resultados em uma tabela temporária e atender a todas as referências a partir dessa tabela. Isso é especialmente útil quando a mesma CTE é referenciada várias vezes em uma consulta (por exemplo, em autorjunções ou em várias subconsultas IN), porque o cálculo subjacente ocorre apenas uma vez.
CTEs materializadas são um recurso experimental. Elas exigem que o analisador e a configuração enable_materialized_cte estejam habilitados.

Sintaxe

Quando usar

CTEs materializadas são mais vantajosas quando:
  • A mesma CTE é referenciada mais de uma vez em uma consulta. Sem MATERIALIZED, cada referência executa a subconsulta novamente, de forma independente.
  • A CTE contém funções não determinísticas, como generateRandom. A materialização garante que todas as referências vejam os mesmos dados.
  • A CTE envolve computações custosas (agregações, junções, varreduras extensas) que não devem ser repetidas.
Se uma CTE materializada for referenciada apenas uma vez, o ClickHouse a incorpora automaticamente novamente como uma subconsulta normal para evitar sobrecarga desnecessária.

Exemplos

Exemplo 1: autorjunção em uma CTE materializada Sem MATERIALIZED, os dois lados da junção executariam a subconsulta de forma independente. Com MATERIALIZED, a tabela é lida uma vez, e os dois lados da junção leem da mesma tabela temporária.
Exemplo 2: Resultados determinísticos com funções não determinísticas CTEs regulares com generateRandom produzem resultados diferentes a cada referência. Materializar a CTE garante consistência:
Como ambas as referências leem dos mesmos dados materializados, o resultado é sempre 1000000. Exemplo 3: Encadeamento de CTEs materializadas CTEs materializadas podem fazer referência a outras CTEs materializadas. O ClickHouse resolve as dependências e as materializa na ordem correta:
A ordem das definições de CTE não importa — referências futuras são permitidas:

Restrições

  • Configuração experimental obrigatória: A configuração enable_materialized_cte deve estar habilitada.
  • Analisador obrigatório: CTEs materializadas só funcionam com o analisador habilitado (enable_analyzer = 1).
  • Sem suporte a RECURSIVE: Não é permitido combinar as palavras-chave MATERIALIZED e RECURSIVE, e isso resulta em uma exceção UNSUPPORTED_METHOD.
  • CTEs correlacionadas são proibidas: Uma CTE materializada não pode referenciar colunas de escopos externos da consulta.

Expressões escalares comuns

O ClickHouse permite declarar aliases para expressões escalares arbitrárias na cláusula WITH. Expressões escalares comuns podem ser referenciadas em qualquer ponto da consulta.
Se uma expressão escalar comum fizer referência a algo diferente de um literal constante, ela poderá levar à presença de variáveis livres. O ClickHouse resolve qualquer identificador no escopo mais próximo possível, o que significa que variáveis livres podem referenciar entidades inesperadas em caso de conflito de nomes ou levar a uma subconsulta correlacionada. Recomenda-se definir a CSE como uma função lambda (possível apenas com o analisador habilitado), vinculando todos os identificadores usados para obter um comportamento mais previsível na resolução dos identificadores da expressão.

Sintaxe

Exemplos

Exemplo 1: Usando uma expressão constante como “variável”
Exemplo 2: Usando funções de ordem superior para delimitar identificadores
Exemplo 3: Uso de funções de ordem superior com variáveis livres As consultas de exemplo a seguir mostram que identificadores não associados são resolvidos para uma entidade no escopo mais próximo. Aqui, extension não está associada no corpo da função lambda gen_name. Embora extension seja definida como '.txt' como uma expressão escalar comum no escopo da definição e do uso de generated_names, ela é resolvida como uma coluna da tabela extension_list, porque está disponível na subconsulta generated_names.
Exemplo 4: Removendo o resultado da expressão sum(bytes) da lista de colunas da cláusula SELECT
Exemplo 5: Usando os resultados de uma subconsulta escalar
Exemplo 6: Reutilização de expressão em uma subconsulta

Consultas recursivas

O modificador opcional RECURSIVE permite que uma consulta WITH faça referência ao próprio resultado. Exemplo: Exemplo: Somar números inteiros de 1 a 100
As CTEs recursivas dependem do analisador de consultas, introduzido na versão 24.3. Se você estiver usando a versão 24.3+ e encontrar uma exceção (UNKNOWN_TABLE) ou (UNSUPPORTED_METHOD), isso sugere que o analisador está desabilitado na sua instância, role ou perfil. Para ativar o analisador, habilite a configuração allow_experimental_analyzer ou atualize a configuração compatibility para uma versão mais recente. A partir da versão 24.8, o analisador foi oficialmente promovido para produção, e a configuração allow_experimental_analyzer foi renomeada para enable_analyzer.
A forma geral de uma consulta WITH recursiva é sempre: um termo não recursivo, depois UNION ALL e, em seguida, um termo recursivo, em que apenas o termo recursivo pode conter uma referência à própria saída da consulta. A consulta de CTE recursiva é executada da seguinte forma:
  1. Avalie o termo não recursivo. Coloque o resultado da consulta do termo não recursivo em uma tabela de trabalho temporária.
  2. Enquanto a tabela de trabalho não estiver vazia, repita estas etapas:
    1. Avalie o termo recursivo, substituindo a autorreferência recursiva pelo conteúdo atual da tabela de trabalho. Coloque o resultado da consulta do termo recursivo em uma tabela intermediária temporária.
    2. Substitua o conteúdo da tabela de trabalho pelo conteúdo da tabela intermediária e, em seguida, esvazie a tabela intermediária.
Consultas recursivas normalmente são usadas para trabalhar com dados hierárquicos ou estruturados em árvore. Por exemplo, podemos escrever uma consulta que faz o percurso de árvore: Exemplo: Percurso de árvore Primeiro, vamos criar a tabela da árvore:
Podemos percorrer a árvore com a seguinte consulta: Exemplo: Percurso de árvore

Ordem de busca

Para criar uma ordem de percurso em profundidade, calculamos, para cada linha do resultado, um array de linhas que já visitamos: Exemplo: percurso em profundidade na árvore
Para obter uma ordem em largura, a abordagem padrão é adicionar uma coluna que acompanhe a profundidade da busca: Exemplo: Percurso em largura da árvore

Detecção de ciclos

Primeiro, vamos criar a tabela do grafo:
Podemos percorrer esse grafo com a seguinte consulta: Exemplo: Percurso de grafo sem detecção de ciclos
Mas, se adicionarmos um ciclo a esse grafo, a consulta anterior falhará com o erro Maximum recursive CTE evaluation depth:
O método padrão para lidar com ciclos é calcular um array com os nós já visitados: Exemplo: Percurso de grafo com detecção de ciclos

Consultas infinitas

Também é possível usar consultas com CTE recursiva infinita se LIMIT for usado na consulta externa: Exemplo: Consulta com CTE recursiva infinita

Vírgula à direita

É permitido usar uma vírgula após o último elemento na cláusula WITH:
Última modificação em 1 de julho de 2026