- Categorias:
WITH¶
A cláusula WITH é uma cláusula opcional que precede o corpo da instrução SELECT e define uma ou mais CTEs (expressões comuns da tabela) que podem ser usadas mais tarde na instrução. Por exemplo, CTEs podem ser referenciados na cláusula FROM.
Nota
Você pode usar uma cláusula WITH ao criar e chamar um procedimento anônimo semelhante a um procedimento armazenado. Essa cláusula modifica um comando CALL em vez de um comando SELECT. Para obter mais informações, consulte CALL (com procedimento anônimo).
A cláusula WITH é usada com objetos de modelo de aprendizado de máquina para criar um alias para uma versão específica do modelo, que pode então ser usado para chamar os métodos dessa versão. Consulte Como chamar métodos de modelo.
- Consulte também:
Sintaxe¶
Subconsulta:
CTE recursivo:
Onde:
Parâmetros¶
cte_name1,cte_nameNO nome CTE deve seguir as regras para exibições e identificadores de objetos semelhantes.
cte_column_listOs nomes das colunas no CTE (expressão comum da tabela).
anchor_column_listAs colunas utilizadas na cláusula de âncora para o CTE recursivo. As colunas desta lista devem corresponder às colunas definidas em
cte_column_list.recursive_column_listAs colunas utilizadas na cláusula recursiva para o CTE recursivo. As colunas desta lista devem corresponder às colunas definidas em
cte_column_list.
Para obter mais detalhes, consulte Cláusula de âncora e Cláusula recursiva (neste tópico). Para uma explicação detalhada de como a cláusula de âncora e a cláusula recursiva funcionam em conjunto, consulte Como trabalhar com CTEs (expressões de tabela comuns).
Notas de uso¶
Uso geral¶
Uma cláusula WITH pode se referir recursivamente a si mesma, e a outros CTEs que aparecem anteriormente na mesma cláusula. Por exemplo,
cte_name2pode se referir acte_name1e a si mesmo, enquantocte_name1pode se referir a si mesmo, mas não acte_name2.Você pode misturar cláusulas recursivas e não recursivas (iterativas e não iterativas) CTE na cláusula WITH. As cláusulas CTE devem ser ordenadas de forma que, se um CTE precisar fazer referência a outro CTE, o CTE a ser referenciado deve ser definido mais cedo na instrução (por exemplo, o segundo CTE pode fazer referência ao primeiro CTE, mas não o contrário).
Os CTEs não precisam ser listados em ordem com base no fato de serem recursivos ou não. Por exemplo, um CTE não recursivo pode ser listado imediatamente após a palavra-chave
RECURSIVE, e um CTE recursivo pode vir após esse CTE não recursivo.Dentro de um CTE recursivo, ou a cláusula de âncora ou a cláusula recursiva (ou ambas) podem se referir a outro(s) CTE(s).
Para CTEs recursivos, o
cte_column_listé obrigatório.Para CTEs não recursivos, o
cte_column_listé opcional.Certifique-se de usar
UNION ALL, nãoUNION, em um CTE recursivo.A palavra-chave
RECURSIVEé opcional.CTEs pode ser recursivo, com
RECURSIVEespecificado ou não.Você pode usar a palavra-chave
RECURSIVEmesmo que nenhum CTEs seja recursivo.Se
RECURSIVEfor usado, deve ser usado apenas uma vez, mesmo que mais de um CTE seja recursivo.
Embora as instruções SQL funcionem corretamente com ou sem a palavra-chave
RECURSIVE, o uso correto da palavra-chave torna o código mais fácil de entender e manter. O Snowflake recomenda o uso da palavra-chaveRECURSIVEse um ou mais CTEs forem recursivos, e o Snowflake recomenda fortemente a omissão da palavra-chave se nenhum dos CTEs for recursivo.
Atenção
Ao utilizar um CTE recursivo, é possível criar uma consulta que entra em um loop infinito e consome créditos até que a consulta seja bem sucedida, o tempo de consulta expire (por exemplo, excede o número de segundos especificado pelo parâmetro STATEMENT_TIMEOUT_IN_SECONDS) ou você cancele a consulta.
Para obter mais informações sobre como podem ocorrer loops infinitos e para diretrizes sobre como evitar este problema, consulte Solução de problemas de uma CTE recursiva.
Por exemplo, para limitar o número de iterações a menos de 10:
Limitações¶
A implementação do Snowflake de CTEs recursivos não oferece suporte às seguintes palavras-chave que alguns outros sistemas suportam:
SEARCH DEPTH FIRST BY ...CYCLE ... SET ...
Cláusula de âncora¶
A cláusula de âncora em um CTE recursivo é uma instrução SELECT.
A cláusula de âncora é executada uma vey durante a execução da instrução na qual está inserida; ela é executada antes da cláusula recursiva e gera o primeiro conjunto de linhas a partir do CTErecursivo. Estas linhas não só estão incluídas na saída da consulta, mas também referenciadas pela cláusula recursiva.
A cláusula de âncora pode conter qualquer construção SQL permitida em uma cláusula SELECT. No entanto, a cláusula de âncora não pode fazer referência a cte_name1; somente a cláusula recursiva pode fazer referência a cte_name1.
Embora a cláusula de âncora geralmente faça a seleção da mesma tabela que a cláusula recursiva, isto não é necessário. A cláusula de âncora pode fazer a seleção de qualquer fonte de dados do tipo tabela, incluindo outra tabela, uma exibição, um UDTF ou um valor constante.
A cláusula de âncora seleciona um único “nível” da hierarquia, tipicamente o nível superior, ou o nível mais alto de interesse. Por exemplo, se a consulta se destina a mostrar a “explosão de peças” de um carro, a cláusula de âncora retorna o componente de nível mais alto, que é o próprio carro.
A saída da cláusula de âncora representa uma camada da hierarquia, e esta camada é armazenada como o conteúdo da “exibição” que é acessada na primeira iteração da cláusula recursiva.
Cláusula recursiva¶
A cláusula recursiva é uma instrução SELECT. Este SELECT é restrito a projeções, filtros e junções (junções internas e externas nas quais a referência recursiva está no lado preservado da junção externa). A cláusula recursiva não pode conter:
Funções agregadas ou de janela,
GROUP BY,ORDER BY,LIMITouDISTINCT.
A cláusula recursiva pode (e geralmente faz) referência ao cte_name1 como se o CTE fosse uma tabela ou exibição.
A cláusula recursiva geralmente inclui um JOIN que une a tabela que foi usada na cláusula de âncora ao CTE. Entretanto, o JOIN pode juntar-se a mais de uma tabela ou fonte de dados em forma de tabela (exibição etc.).
A primeira iteração da cláusula recursiva começa com os dados da cláusula de ancoragem. Esses dados são então unidos à(s) outra(s) tabela(s) na cláusula FROM da cláusula recursiva.
Cada iteração subsequente começa com os dados da iteração anterior.
Você pode pensar na cláusula CTE ou “exibição” como se estivesse mantendo o conteúdo da iteração anterior, de modo que esse conteúdo esteja disponível para ser unido. Observe que durante qualquer iteração, o CTE contém apenas o conteúdo da iteração anterior, não os resultados acumulados de todas as iterações anteriores. Os resultados acumulados (inclusive a partir da cláusula de ancoragem) são armazenados em um local separado.
Listas de colunas em um CTE recursivo¶
Há três listas de colunas em um CTE recursivo:
cte_column_listanchor_column_list(na cláusula de ancoragem)recursive_column_list(na cláusula recursiva)
Um CTE recursivo pode conter outras listas de colunas (por exemplo, em uma subconsulta), mas estas três listas de colunas devem obrigatoriamente estar presentes.
Estas três listas de colunas devem corresponder umas às outras.
Em pseudocódigo, isto é semelhante a:
As colunas X e related_to_X devem ser correspondentes; a cláusula de âncora gera o “conteúdo” inicial da “exibição” que o CTE representa, portanto cada coluna da cláusula de âncora (por exemplo, coluna related_to_x) deve gerar a saída que pertencerá à coluna correspondente do CTE (por exemplo, coluna X).
As colunas also_related_to_X e X devem ser correspondentes; em cada iteração da cláusula recursiva, a saída dessa cláusula torna-se o novo conteúdo do CTE/exibição para a próxima iteração.
Além disso, as colunas related_to_X e also_related_to_X devem corresponder porque estão cada uma de um lado do operador UNION ALL, e as colunas de cada lado de um operador UNION ALL devem corresponder.
Exemplos¶
Exemplos não recursivos¶
Esta seção fornece exemplos de consultas e saída. Para manter os exemplos curtos, o código omite as instruções para criar e carregar as tabelas.
Este primeiro exemplo usa uma simples cláusula WITH para extrair um subconjunto de dados, neste caso os álbuns de música que foram lançados em 1976. Para este pequeno banco de dados, a saída da consulta são os álbuns “Amigos” e “Look Into The Future”, ambos do ano 1976:
Este próximo exemplo usa uma cláusula WITH com uma cláusula WITH anterior; o CTE chamado journey_album_info_1976 usa o CTE chamado album_info_1976. A saída é o álbum “Look Into The Future”, com o nome da banda:
Este exemplo lista os músicos que tocaram nos álbuns do Santana e do Journey. Este exemplo não utiliza a cláusula WITH. Para esta consulta (e as próximas consultas, todas sendo as formas equivalentes de executar a mesma consulta), a saída são IDs e os nomes dos músicos que tocaram nos álbuns do Santana e nos álbuns do Journey:
Como você pode ver, a consulta anterior contém um código duplicado. Os próximos exemplos mostram como simplificar esta consulta usando uma ou mais exibições explícitas, e depois como simplificá-la usando CTEs.
Esta consulta mostra como usar as exibições para reduzir a duplicação e complexidade do exemplo anterior (como no exemplo anterior, isto não usa uma cláusula WITH):
Com esta exibição, você pode reescrever a consulta original como:
Este exemplo usa uma cláusula WITH para fazer o equivalente ao que a consulta anterior fez:
Estas instruções criam exibições mais granulares (este exemplo não usa uma cláusula WITH):
Listar os álbuns por uma determinada banda:
Listar os músicos que tocaram nos álbuns:
Agora use essas exibições para consultar os músicos que tocaram em ambos os álbuns do Santana e do Journey:
Estas instruções criam exibições implícitas e mais granulares (este exemplo usa uma cláusula WITH):
Exemplos recursivos¶
Este é um exemplo básico da utilização de um CTE recursivo para gerar uma sequência de Fibonacci:
Este exemplo é uma consulta com um CTE recursivo que mostra uma “explosão de peças” para um automóvel:
Para obter mais exemplos, consulte Como trabalhar com CTEs (expressões de tabela comuns).