Se analisarmos a evolução das consultas em bancos de dados, percebemos que, a cada necessidade de agregar, filtrar ou segmentar informações, buscamos novas formas de tornar nosso SQL mais claro e poderoso. Ao longo do tempo, as Expressões de Tabela Comum, as famosas CTEs, se destacaram por simplificar consultas complexas e permitir divisão lógica dos scripts sem perder a performance e a legibilidade. Nesta jornada, queremos compartilhar nossa experiência no uso de CTEs, abordando conceitos essenciais, diferenças entre CTE, subquery e view, além de trazer sete exemplos práticos que, de fato, fazem diferença no dia a dia de quem trabalha com dados.
O que é uma CTE e por que ela torna as consultas SQL mais acessíveis?
CTE (Common Table Expression), ou Expressão de Tabela Comum, é uma estrutura temporária e nomeada de consulta que existe apenas na execução de um statement SQL. Ela permite quebrar etapas em subconsultas claras e reutilizáveis, sem necessidade de criar tabelas permanentes ou alterar a estrutura do banco.
Sua principal função é tornar o código mais organizado e fácil de manter. Em nossa experiência atendendo gestores e times técnicos, notamos que a clareza proporcionada pelas CTEs faz com que diagnósticos de problemas fiquem mais rápidos e adaptações em consultas extensas ocorram com menos riscos.
Clareza gera confiança, e confiança traz resultados nos dados.
Criando uma CTE: a sintaxe básica no SQL
Para criar uma CTE, usamos quase sempre a palavra-chave WITH antes da consulta principal. A estrutura básica é:
WITH nome_da_cte AS ( SELECT ... FROM ... WHERE ...)SELECT ...FROM nome_da_cte...
Uma das vantagens é a possibilidade de encadear múltiplas CTEs na mesma declaração, separando por vírgula e depois conectando à query final. Isso simplifica etapas e dá possibilidade de reaproveitamento de logic das consultas anteriores.
Existem dois principais tipos:
- CTE não recursiva: Executa apenas uma vez, como uma subconsulta temporária para uma etapa da consulta.
- CTE recursiva: Permite que a declaração se chame a si mesma, ideal para resolver relações hierárquicas.
Principais diferenças: CTE, subquery e view
Antes dos exemplos práticos, é válido comparar a CTE com outras formas comuns de organizar consultas no SQL:
- Subquery: É uma consulta dentro de outra, geralmente identificada por SELECT ... FROM (SELECT ...). Costuma gerar códigos mais difíceis de ler caso haja muitas camadas e relações.
- View: Cria uma consulta salva no banco, podendo ser reutilizada em diversos momentos. Diferente da CTE, a view é persistente, demandando manutenção direta no banco caso o modelo mude.
- CTE: Fica entre uma subquery e uma view. É temporária (apenas durante a execução daquele statement) e serve principalmente para deixar o código organizado, modularizado e fácil de depurar.
Como resultado, a escolha entre essas três técnicas depende do contexto, frequência de uso da consulta e necessidade de performance e manutenção.
Simplificando situações complexas: 7 exemplos práticos de uso de CTE
Vamos apresentar agora sete situações que vivenciamos e nas quais a CTE foi uma aliada. Selecionamos contextos e estruturas variadas para ajudar quem busca como criar CTE no SQL, desde o simples até casos que exigem recursividade e agregações especiais.
1. Agregação em múltiplos passos
Imagine que precisamos identificar o faturamento total por categoria de produto e, logo em seguida, calcular a média dos maiores faturamentos. Com uma CTE, tornamos o código limpo:
WITH faturamento_categoria AS ( SELECT categoria, SUM(valor) AS total FROM vendas GROUP BY categoria)SELECT AVG(total) AS media_maiores FROM faturamento_categoria WHERE total > 10000;
Em vez de aninhar subconsultas, filtramos e agregamos informações de maneira sequencial, facilitando mudanças futuras.
2. Filtrando dados com várias regras de negócio
Suponha um cenário em que, primeiro, filtramos clientes ativos, depois, segmentamos por faixa de idade e, por fim, buscamos casos em que o ticket médio supera determinado valor. Ao usar CTEs, podemos dividir cada etapa:
WITH clientes_ativos AS (
SELECT *
FROM clientes
WHERE status = 'Ativo'),clientes_faixa_idade AS (
SELECT *, EXTRACT(YEAR FROM AGE(data_nascimento)) as idade
FROM clientes_ativos
WHERE EXTRACT(YEAR FROM AGE(data_nascimento))
BETWEEN 30 AND 50)SELECT nome, idade, ticket_medio
FROM clientes_faixa_idade
WHERE ticket_medio > 500;
Essa estrutura modular evita cópia e colagem de condições em diferentes pontos do SQL.
3. Simular tabelas temporárias para reutilização
Ao trabalhar com dados que precisam ser tratados em etapas, como normalizações ou fusões de diferentes fontes, a CTE serve como uma “tabela temporária” no escopo da query:
WITH base_normalizada AS (
SELECT id, UPPER(nome) as nome_norm, valor*1.15 as valor_corrigido
FROM pedidos
WHERE data >= '2024-01-01')SELECT nome_norm, SUM(valor_corrigido)
FROM base_normalizada
GROUP BY nome_norm;
Repare como evitamos criar tabelas físicas a cada ajuste intermediário, reduzindo burocracia e riscos.
4. Estruturar consultas hierárquicas com CTE recursiva
Em engenharia de dados, é comum lidar com estruturas hierárquicas, organogramas, arborescências de categorias, cadeias de processos produtivos. Para esses casos, uma CTE recursiva resolve de forma elegante:
WITH RECURSIVE hierarquia_categorias AS (
SELECT id, nome, id_pai, 1 AS nivel
FROM categorias
WHERE id_pai IS NULL
UNION ALL SELECT c.id, c.nome, c.id_pai, hc.nivel + 1
FROM categorias c
INNER JOIN hierarquia_categorias hc
ON c.id_pai = hc.id)SELECT *
FROM hierarquia_categorias;
Essa técnica permite desdobrar árvores organizacionais em uma única consulta, com total controle sobre nível e relação entre itens.
5. Separar etapas em códigos legíveis e fáceis de depurar
Durante auditorias, muitas vezes precisamos quebrar consultas complexas em partes para encontrar erros de cálculos, identificar duplicidades ou analisar tendências específicas.
- Permite nomear cada subetapa de acordo com a regra de negócio.
- Facilita a inclusão de debugs progressivamente.
- Aumenta o entendimento coletivo da lógica, especialmente em times multidisciplinares.
WITH duplicatas AS (
SELECT id_cliente, COUNT(*) as vezes
FROM vendas
GROUP BY id_cliente
HAVING COUNT(*) > 1),detalhes_duplicatas AS (
SELECT v.*
FROM vendas v
INNER JOIN duplicatas d
ON v.id_cliente = d.id_cliente)SELECT * FROM detalhes_duplicatas;
Separar cada lógica não só garante um código limpo, como reduz a necessidade de retrabalhos.
6. Ajuste de regras de negócio conforme mudanças na empresa
Outro ponto que aprendemos na experiência em projetos é que regras de negócio mudam, descontos, comissões e limites são revisados quase todo mês. A CTE, por ser localizada dentro da consulta, pode ser rapidamente adaptada sem mudar as estruturas do banco todo.
WITH comissoes_calculadas AS (
SELECT vendedor, SUM(valor_venda)*0.05 as comissao
FROM vendas
WHERE data > date_trunc('month', CURRENT_DATE)
GROUP BY vendedor)SELECT vendedor, comissao
FROM comissoes_calculadas
WHERE comissao > 500;
Basta ajustar a fórmula em apenas uma linha da CTE para atender uma nova política empresarial.
7. Estratégia para segmentar clientes e personalizar campanhas
Em projetos de marketing orientado a dados, é comum precisar identificar segmentos rapidamente para campanhas sazonais. Com uma CTE, segmentamos clientes em faixas e cruzamos com preferências de compra, otimizando recursos:
WITH clientes_potenciais AS (
SELECT id, nome, idade
FROM clientes
WHERE idade BETWEEN 25 AND 35),preferencias AS (
SELECT id_cliente, COUNT(*) as compras_saude
FROM compras
WHERE categoria = 'Saúde'
GROUP BY id_cliente)SELECT c.nome
FROM clientes_potenciais c
INNER JOIN preferencias p
ON c.id = p.id_cliente
WHERE p.compras_saude >= 3;
Essa flexibilidade possibilita entregar valor de forma ágil, sem dependência de processos longos ou infraestruturas burocráticas.
Comparando: quando usar CTE, subquery ou view?
Baseado em nossa vivência, sugerimos alguns critérios práticos:
- Use CTE quando quiser dividir sua consulta em blocos claros e temporários, especialmente em análises ad hoc ou scripts que mudam com frequência. A nossa série prática sobre SQL detalha mais sobre padrões de consultas em projetos reais.
- Prefira subquery para lógicas pontuais, onde a reutilização ou separação em etapas não é necessária.
- Opte pela view quando a mesma consulta for usada repetidamente por diferentes times ou sistemas.
A modularidade da CTE contribui para um código mais fácil de ler, compartilhar e evoluir, ao mesmo tempo reduzindo as chances de erros ocultos.
Equilíbrio entre clareza e performance define o sucesso de uma análise de dados.
Dicas para evitar erros comuns com CTE e escalar com segurança
- Sempre nomeie suas CTEs de acordo com o propósito (ex: usuarios_ativos, vendas_mensais).
- Evite repetições desnecessárias, se precisa referenciar muitas vezes a mesma lógica complexa, talvez já seja o caso de criar uma view persistente.
- Tenha atenção com performance: em bancos muito grandes, o uso abusivo de múltiplas CTEs pode gerar planos de execução pesados, revise o plano antes de executar scripts em produção.
- Lembre-se de que a CTE existe apenas no escopo da consulta; resultados não ficam salvos no banco ao término da query.
- Testes progressivos ajudam a perceber gargalos. Recomendamos validar cada CTE isoladamente antes de encadear várias na mesma execução.
Caso esteja buscando aprofundar seu entendimento sobre como projetos de dados tratam grandes volumes e diferentes fontes, nossa publicação sobre análise e processamento com Apache Spark apresenta as melhores práticas para volume, carga e manutenção.
Cuidados de performance: CTEs em ambientes de alto volume
Quando as bases têm bilhões de linhas, toda escolha de modelagem e escrita influencia diretamente no tempo da análise e nos custos. Algumas dicas práticas:
- Evite CTEs recursivas muito profundas: limitações de memória podem gerar falhas ou lentidão.
- Filtre dados o quanto antes na CTE, para não trabalhar com conjuntos desnecessariamente grandes.
- Esteja atento ao uso de JOIN em múltiplas CTEs, se não for feito corretamente, pode provocar o famoso efeito “cross join involuntário”.
Em engenharia de dados, sempre validamos o plano de execução para identificar gargalos, o artigo sobre engenharia de dados reúne dicas diretas para quem trabalha em projetos sensíveis a performance.
Manutenção e legibilidade: o poder da modularidade com CTE
No final do dia, consultas SQL que usam CTEs tendem a ser mais fáceis de ler, adaptar e debugar, tornando-se aliadas na rotina dos analistas. Divida as responsabilidades da consulta em pedaços pequenos, nomeados e compreensíveis, assim, qualquer pessoa que ler seu código saberá rapidamente o que está acontecendo, mesmo sem ter participado da escrita original.
Manutenção não é apenas sobre corrigir falhas, mas sobre permitir evolução sem traumas. Ao criar consultas que se explicam sozinhas, aceleramos entregas e reduzimos incidentes.
E, falando em qualidade, o artigo sobre como garantir a qualidade dos dados em projetos analytics aprofunda a relação entre arquitetura de consultas e a entrega de insights confiáveis.
Onde buscar mais conteúdos sobre SQL, CTEs e engenharia de dados?
Recomendamos consultar nosso acervo na página sobre Databricks para exemplos avançados de engenharia, além de outros temas que conectam boas práticas e ferramentas modernas em análise de dados. O blog é atualizado com rotinas, experiências do mercado e estratégias para acelerar a entrega de resultados concretos nas empresas.
Conclusão: CTE como aliada da clareza e evolução constante
Como vimos, saber como criar CTE no SQL e conhecer exemplos para descomplicar consultas traz um novo ritmo para a rotina de dados. Em cada cenário, dos mais simples aos altamente hierárquicos —, as Expressões de Tabela Comum permitem modularidade, legibilidade e facilidade de evolução das análises.
Na DW Intelligence é transformar conhecimento técnico em impacto prático, guiando decisões que realmente agregam valor. Se quer compreender melhor como estruturar projetos de dados sólidos, acesse nossos conteúdos ou entre em contato, queremos ser parte da sua jornada rumo a soluções mais simples, claras e confiáveis.
Perguntas frequentes sobre CTE no SQL
O que é uma CTE no SQL?
CTE, ou Expressão de Tabela Comum, é uma consulta temporária nomeada, criada com a palavra-chave WITH, que existe só durante a execução da query. Ela permite organizar etapas intermediárias em um SQL, facilitando a leitura e manutenção do código.
Como criar uma CTE passo a passo?
Primeiro, escreva a estrutura com WITH nome_da_cte AS (SELECT ...). Inclua a lógica desejada dentro dos parênteses. Depois, na query principal, consulte pelo nome definido da CTE, como se fosse uma tabela. Esse padrão pode ser repetido para várias etapas, separando diferentes lógicas no mesmo statement.
Quais são os benefícios das CTEs?
As CTEs aumentam a legibilidade, organizam consultas complexas por etapas e facilitam depuração. Elas tornam o SQL mais modular, simples de ajustar conforme mudanças e evitam duplicidade de código. Também melhoram o entendimento coletivo do processo nos times de dados.
CTE substitui subquery no SQL?
Em muitos casos, sim, pois a CTE deixa o código mais organizado quando comparada a subqueries aninhadas. No entanto, para condições muito simples e pontuais, a subquery ainda pode ser mais direta. O ideal é avaliar cada cenário, priorizando clareza e facilidade de manutenção.
Quando devo usar CTE em consultas SQL?
Opte por CTE sempre que a consulta tiver múltiplas regras de negócio, muitos passos de tratamento de dados ou precisar de clareza para futuras alterações. Sua aplicação é especialmente valiosa em scripts que exigem manutenção frequente, auditorias ou compartilhamento entre equipes.
