Ícone do site SOLOWEB Tecnologia

Melhorando desempenho de consultas SQL com CTE (Common Table Expressions)

Neste tutorial, você aprenderá como usar o CTE (common table expression) ou expressão de tabela comum, também são chamadas de “WITH querys”, e sua finalidade é simplificar consultas complexas e geralmente melhora o desempenho.

Uma CTE é um conjunto de resultados temporário que você pode fazer referência em outra instrução SQL, incluindo SELECT, INSERT, UPDATE e DELETE.

As Expressões de Tabela Comuns são temporárias no sentido de que só existem durante a execução da consulta.

CTE existe nos principais banco de dados, por exemplo: Oracle, SqlServer, MySql, MariaDB, SQLite e outros, em nossos exemplos vamos utilizar o PostgreSQL como base.

Vantagens de usar CTE
A seguir estão algumas vantagens de usar expressões de tabela comuns ou CTEs:

Veja a seguir a sintaxe de criação de um CTE:

Primeiro defina o nome e as colunas do CTE.

WITH cte_identificador (coluna1, coluna2)  
AS 

Em seguida o corpo da consulta.

WITH cte_identificador (coluna1, coluna2)
AS (
  SELECT 1, 2
)

Por último, defina a consulta externa, que fará referência ao nome CTE.

WITH cte_identificador (coluna1, coluna2)  
AS (  
    SELECT 1, 2 
   ) 
SELECT * FROM cte_identificador

Você também pode fazer CTEs recursivo, adicionando a palavra chave: “recursive”! Depois de adicionar “recursive”, o Postgres agora permite que você faça referência ao seu CTE de dentro de si mesmo, permitindo que você “gere” linhas com base na recursão.

Agora um exemplo simples.

Vamos supor que queremos saber qual foi a média da turma e qual média dos alunos foi maior que a média da turma? Qual foi a média de cada um desses alunos?

Uma solução utilizando CTE:

WITH cte_media_aluno  AS (
	SELECT id_aluno, ROUND(AVG(nota),2) as media_aluno
        FROM tb_notas 
        GROUP BY tb_notas.id_aluno
), 
cte_media_turma AS (
	SELECT ROUND(AVG(nota),2) as media_sala
        FROM tb_notas 
)

SELECT id_aluno, media_aluno, cte_media_turma.media_sala
FROM cte_media_aluno
JOIN cte_media_turma  ON TRUE
WHERE media_aluno > media_sala;

Temos o seguinte resultado:

Agora vamos observar a solução sem utilizar CTE:

SELECT id_aluno, media_aluno, nt.media_sala
FROM (
 SELECT id_aluno, ROUND(AVG(nota),2) as media_aluno
        FROM tb_notas 
        GROUP BY tb_notas.id_aluno
) 
JOIN (
 SELECT ROUND(AVG(nota),2) as media_sala
        FROM tb_notas 
)  AS nt
    ON TRUE
WHERE media_aluno > media_sala;

Fica bem visível que a consulta com CTE melhora a legibilidade da consulta e consequentemente manutenção futura já que separamos bem cada informação que precisamos.

Também é fácil observar que quanto mais complexo é sua consultar melhor se encaixa os CTE.

Só para esclarecer, os CTEs têm seu lugar. Eles tornam o código mais fácil de ler, mas não é apropriado para qualquer consulta SQL.

No próximo post vamos mostrar mais exemplos e os reais resultados ao usar CTE.

Esperamos ter ajudado com esta dica, siga nos para mais dicas.

Sair da versão mobile