Expressões de tabela comuns
As expressões de tabela comuns representam subconsultas nomeadas. Elas podem ser referenciadas pelo nome em qualquer consultaSELECT 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: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-chaveMATERIALIZED 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 a configuração
enable_materialized_cte esteja habilitada.
Se a configuração estiver desabilitada, a palavra-chave MATERIALIZED é ignorada: a CTE é incorporada em cada referência como uma CTE comum, e um aviso é registrado no log.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.
Exemplos
Exemplo 1: autorjunção em uma CTE materializada SemMATERIALIZED, 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.
generateRandom produzem resultados diferentes a cada referência.
Materializar a CTE garante consistência:
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:
Restrições
- Configuração experimental obrigatória: A configuração
enable_materialized_ctedeve estar habilitada. Se estiver desabilitada, a palavra-chaveMATERIALIZEDé ignorada: a CTE é incorporada em cada referência como uma CTE comum, e um aviso é registrado no log. - Sem suporte a
RECURSIVE: Não é permitido combinar as palavras-chaveMATERIALIZEDeRECURSIVE, e isso resulta em uma exceçãoUNSUPPORTED_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áusulaWITH.
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, 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”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.
sum(bytes) da lista de colunas da cláusula SELECT
Consultas recursivas
O modificador opcionalRECURSIVE 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, que é o padrão desde essa versão e obrigatório desde 26.9. Em versões mais antigas, se o analisador ainda estiver desabilitado na instância, na função ou no perfil, uma CTE recursiva gera uma exceção (UNKNOWN_TABLE) ou (UNSUPPORTED_METHOD); nesses casos, habilite a configuração enable_analyzer ou faça o upgrade.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:
- Avalie o termo não recursivo. Coloque o resultado da consulta do termo não recursivo em uma tabela de trabalho temporária.
- Enquanto a tabela de trabalho não estiver vazia, repita estas etapas:
- 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.
- Substitua o conteúdo da tabela de trabalho pelo conteúdo da tabela intermediária e, em seguida, esvazie a tabela intermediária.
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 árvoreDetecção de ciclos
Primeiro, vamos criar a tabela do grafo:Maximum recursive CTE evaluation depth:
Consultas infinitas
Também é possível usar consultas com CTE recursiva infinita seLIMIT 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áusulaWITH: