Pular para o conteúdo

Compreendendo Common Table Expressions (CTEs) em SQL: benefícios e exemplos práticos

Introdução às Common Table Expressions (CTEs)

As CTEs são uma maneira poderosa de organizar e simplificar consultas SQL complexas. Usando a cláusula WITH, você pode criar expressões temporárias que melhoram a legibilidade, manutenção e, em alguns casos, o desempenho das consultas.

Elas são especialmente úteis em cenários onde a mesma subconsulta é utilizada repetidamente, ou quando uma consulta possui muitos níveis de aninhamento. Além disso, CTEs são mais legíveis do que subconsultas tradicionais e podem reduzir o overhead computacional, dependendo do otimizador do banco de dados.

Exemplos de uso

SQL
WITH table_example AS (
    -- Subconsulta
    SELECT coluna1, coluna2
    FROM tabela
WHERE condição
)
SELECT *
FROM table_example;

No próximo exemplo é possível ver uma query sem o uso do WITH e outra adotando a solução:

SQL
SELECT cod_cliente, COUNT(*) AS tot_vendas
FROM vendas
WHERE status = 'FINALIZADO'
GROUP BY cod_cliente;

SELECT cod_cliente, SUM(vl_pedido) AS tot_valor
FROM vendas
WHERE status = 'FINALIZADO'
GROUP BY cod_cliente;

Solução aplicando o WITH:

SQL
WITH vendas_realizadasAS (
    SELECT cod_cliente, vl_pedido
    FROM vendas
    WHERE status = 'FINALIZADO'
)
SELECT cod_cliente, COUNT(*) AS tot_vendas, SUM(vl_pedido) AS tot_valor
FROM vendas_realizadas
GROUP BY cod_cliente;

Nos exemplos acima vemos como a consulta fica mais clara e legível com o uso do CTE, permitindo assim um fácil entendimento bem como uma melhoria de perfomance e evirando repetição de queries, que são vantagens que buscamos com a utilização do CTE.

Assim como no caso abordado acima, existem outros exemplos do uso da clausula WITH fazendo JOIN com outras tabelas e criando assim consultas mais complexas.

Um exemplo de utilização fazendo JOIN com outras tabelas é possível ver abaixo onde listamos os funcionários que não são gerentes, ou seja, que não possuem subordinados:

SQL
WITH subordinados AS (
    SELECT id_gerente AS gerente_id
    FROM funcionarios
    WHERE id_gerente IS NOT NULL
)
SELECT f.id_funcionario, f.nome
FROM funcionarios f , subordinados s 
WHERE f.id_funcionario = s.gerente_id
AND s.gerente_id IS NULL;

Para finalizar, um ponto importante no banco de dados Oracle, é que as CTEs são frequentemente materializadas (inline view). Isso significa que a consulta é executada uma vez e reutilizada, reduzindo o overhead. Podemos usar o hint /*+ MATERIALIZE */ para forçar a materialização se necessário.

SQL
WITH /*+ MATERIALIZE */ cte_table_name AS (
    SELECT ...
)
SELECT ...
FROM cte_table_name;

Benefícios do uso do WITH

Melhoria na Legibilidade e Manutenção

  • Ao nomear subconsultas, o SQL se torna mais legível e mais fácil de ajustar.

Reuso de Resultados

  • Você pode referenciar a mesma CTE múltiplas vezes em uma consulta.

Simplificação de Consultas Complexas

  • Quebre consultas aninhadas ou cálculos complicados em blocos lógicos.

Redução de Carga Computacional (em alguns casos)

  • CTEs materiais podem ser calculadas uma vez e reutilizadas, economizando esforço computacional.

Compatibilidade com Recursão

  • CTEs permitem consultas recursivas, que são úteis para hierarquias e estruturas de dados como árvores.

Um dos pontos de ateção é evitar o uso para queries simples, uma vez que isso poderá ocasionar o efeito contrário do desejado e adicionar uma complexidade desnecessário reduzindo a eficiência.

Conclusão

O uso de CTEs é uma boa abordagem para simplificar e organizar consultas SQL complexas, reduzir duplicação de código e, em alguns casos, melhorar a performance. Apesar disso, é importante testar sua aplicação em diferentes cenários, pois a performance pode variar dependendo do otimizador do banco de dados e do tamanho dos dados envolvidos, e assim não gerar os ganhos inicialmente esperados.

Espero que assim como nos demais posts, o tópico abordado tenha contribuído no entendimento de mais essa opção existente dentre as inúmeras outras relacionados ao contexto de banco de dados.

Referências

Comentário(s) da Comunidade

    1. Olá Antonio,
      CTEs são mais legíveis do que subconsultas (subqueries) tradicionais e podem reduzir o overhead computacional, dependendo do otimizador do banco de dados. No caso do WITH a query é executada uma vez para pegar os dados e retornar para o restante da query, já nas subqueries é feito mais de uma execução, o que explica essa redução de overhead.

      Obrigado pelo comentário.

Prestigie o autor e deixe o seu comentário:

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Marcações: