25th Jun 2024 8 minutos de leitura O que é uma expressão de tabela comum (CTE) em SQL? Ignacio L. Bisso sql aprender sql cte Índice Os CTEs ajudam a simplificar as consultas Aprendendo expressões comuns de tabela SQL por meio de exemplos Uso de CTEs em consultas SQL Avançado CTEs aninhados em consultas SQL Consultas Recursivas e expressões comuns de tabela As CTEs do SQL são um recurso poderoso A expressão de tabela comum (CTE) é uma construção poderosa do SQL que ajuda a simplificar uma consulta. As CTEs funcionam como tabelas virtuais (com registros e colunas), criadas durante a execução de uma consulta, usadas pela consulta e eliminadas após a execução da consulta. Os CTEs geralmente atuam como uma ponte para transformar os dados das tabelas de origem no formato esperado pela consulta. Perguntas: O que é uma expressão de tabela comum no SQL? Uma Common Table Expression (CTE) é como uma subconsulta nomeada. Ela funciona como uma tabela virtual que somente a consulta principal pode acessar. Os CTEs podem ajudar a simplificar, encurtar e organizar seu código. Uma expressão de tabela comum, ou CTE, é um conjunto de resultados nomeado temporário criado a partir de uma instrução SELECT simples que pode ser usada em uma instrução SELECT subsequente. Cada CTE SQL é como uma consulta nomeada, cujo resultado é armazenado em uma tabela virtual (um CTE) para ser referenciado posteriormente na consulta principal. A melhor maneira de aprender expressões de tabela comuns é praticar. Recomendo o curso interativo da LearnSQL.com.brConsultas Recursivas interativo. Ele contém mais de 100 exercícios que ensinam CTEs, começando com o básico e avançando para tópicos avançados, como expressões recursivas de tabelas comuns. Os CTEs ajudam a simplificar as consultas Vamos começar com a sintaxe de uma expressão de tabela comum. WITH my_cte AS ( SELECT a,b,c FROM T1 ) SELECT a,c FROM my_cte WHERE .... O nome desse CTE é my_ctee a consulta CTE é SELECT a,b,c FROM T1. O CTE começa com a palavra-chave WITH, depois da qual você especifica o nome do seu CTE e, em seguida, o conteúdo da consulta entre parênteses. A consulta principal vem após o parêntese de fechamento e se refere ao CTE. Aqui, a consulta principal (também conhecida como consulta externa) é SELECT a,c FROM my_cte WHERE …. Há muitos exemplos de nível básico nesse excelente artigo introdutório sobre CTEs. Outros artigos introdutórios incluem "Improving Query Readability with Common Table Expressions" (Melhorando a legibilidade da consulta com expressões comuns de tabela) e "When Should I Use a Common Table Expression (CTE)?" (Quando devo usar uma expressão comum de tabela (CTE)?), que explicam as expressões comuns de tabela. Aprendendo expressões comuns de tabela SQL por meio de exemplos Nesta seção, apresentamos alguns exemplos de consultas SQL usando expressões de tabela comuns. Todos os exemplos são baseados em um banco de dados de uma cadeia de lojas de telefones celulares. A tabela salesmostrada abaixo, tem um registro por produto vendido: branchdateselleritemquantityunit_price Paris-12021-12-07CharlesHeadphones A2180 London-12021-12-06JohnCell Phone X22120 London-22021-12-07MaryHeadphones A1160 Paris-12021-12-07CharlesBattery Charger150 London-22021-12-07MaryCell Phone B2290 London-12021-12-07JohnHeadphones A0575 London-12021-12-07SeanCell Phone X12100 No primeiro exemplo, obtemos um relatório com os mesmos registros da tabela sales mas adicionamos uma coluna extra com o preço do item mais caro vendido na mesma filial naquele dia. Para obter o preço do item mais caro, usamos uma expressão de tabela comum como esta: WITH highest AS ( SELECT branch, date, MAX(unit_price) AS highest_price FROM sales GROUP BY branch, date ) SELECT sales.*, h.highest_price FROM sales JOIN highest h ON sales.branch = h.branch AND sales.date = h.date Essa consulta define um CTE SQL chamado highest cujo resultado cria uma tabela virtual. A tabela virtual tem as colunas branch, date e highest_price, que contêm o nome da filial, a data e o preço unitário mais alto vendido naquele dia nessa filial, respectivamente. Em seguida, é executada a consulta externa, que usa a tabela virtual highest tabela virtual como se fosse uma tabela normal. Por fim, juntamos o resultado do CTE highest com a tabela sales tabela. O resultado de toda a consulta é mostrado abaixo: branchdateselleritemquantityunit_pricehighest_ price Paris-12021-12-07CharlesHeadphones A218080 London-12021-12-06JohnCell Phone X22120120 London-22021-12-07MaryHeadphones A116090 Paris-12021-12-07CharlesBattery Charger15080 London-22021-12-07MaryCell Phone B229090 London-12021-12-07JohnHeadphones A0575100 London-12021-12-07SeanCell Phone X12100100 No próximo exemplo, geramos um relatório com a maior receita diária por filial. WITH daily_revenue AS ( SELECT branch, date, SUM(unit_price * quantity) AS daily_revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 GROUP BY 1,2 ) SELECT branch, MAX(daily_revenue) max_daily_revenue FROM daily_revenue GROUP BY 1 ORDER BY 2 DESC Nessa consulta, um CTE chamado daily_revenue tem colunas branch, date e daily_revenue para cada data em 2021. Em seguida, na consulta externa, obtemos o maior valor de receita para cada filial em 2021. O relatório é ordenado por max_daily_revenue em ordem decrescente. Abaixo estão os resultados dessa consulta. branchmax_daily_revenue London-1575 London-2240 Paris-1135 Uso de CTEs em consultas SQL Avançado Você pode definir dois ou mais CTEs e usá-los na consulta principal. No próximo exemplo, mostraremos como dividir e organizar uma consulta longa usando CTEs SQL. Ao nomear diferentes partes da consulta, os CTEs facilitam a leitura da consulta. Suponhamos que queremos um relatório com a receita mensal total em Londres em 2021, mas também queremos a receita de cada filial em Londres no mesmo relatório. Aqui, criamos dois CTEs e depois os unimos na consulta principal. WITH london1_monthly_revenue AS ( SELECT EXTRACT(MONTH FROM date) as month, SUM(unit_price * quantity) AS revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 AND branch = 'London-1' GROUP BY 1 ), london2_monthly_revenue AS ( SELECT EXTRACT(MONTH FROM date) as month, SUM(unit_price * quantity) AS revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 AND branch = 'London-2' GROUP BY 1 ) SELECT l1.month, l1.revenue + l2.revenue AS london_revenue, l1.revenue AS london1_revenue, l2.revenue AS london2_revenue FROM london1_monthly_revenue l1, london2_monthly_revenue l2 WHERE l1.month = l2.month Na consulta acima, definimos dois CTEs, london1_monthly_revenue e london2_monthly_revenuepara obter a receita mensal em 2021 para cada filial em Londres. Por fim, juntamos os dois CTEs usando a coluna do mês e calculamos a receita total de Londres somando as receitas das duas filiais. O resultado da consulta está abaixo: monthlondon_revenuelondon1_revenuelondon2_revenue 121055815240 No exemplo a seguir, obtemos um relatório para informar a cada filial a data em que o maior tíquete (ou seja, o valor da combinação item-quantidade) foi vendido e o valor desse tíquete. Para fazer isso, precisamos criar um CTE que classifique os tíquetes (a coluna position é a classificação) de cada filial pelo valor do tíquete. WITH tickets AS ( SELECT distinct branch, date, unit_price * quantity AS ticket_amount, ROW_NUMBER() OVER ( PARTITION BY branch ORDER by unit_price * quantity DESC ) AS position FROM sales ORDER BY 3 DESC ) SELECT branch, date, ticket_amount FROM tickets WHERE position =1 Na consulta acima, criamos um CTE com as colunas branch, date, ticket_amount e position. Em seguida, na consulta externa, filtramos apenas os registros com position = 1 para obter o que desejamos, o maior tíquete por filial. O resultado da consulta é mostrado abaixo: branchdateticket_amount London-12021-11-2450 London-22021-11-1270 Paris-12021-12-780 CTEs aninhados em consultas SQL O próximo exemplo mostra um CTE aninhado. A ideia é gerar um relatório com todos os itens com preço acima de US$ 90 e a quantidade desses itens vendidos pela filial de Londres-2. WITH over_90_items AS ( SELECT DISTINCT item, unit_price FROM sales WHERE unit_price >=90 ), london2_over_90 AS ( SELECT o90.item, o90.unit_price, coalesce(SUM(s.quantity), 0) as total_sold FROM over_90_items o90 LEFT JOIN sales s ON o90.item = s.item AND s.branch = 'London-2' GROUP BY o90.item, o90.unit_price ) SELECT item, unit_price, total_sold FROM london2_over_90; O primeiro CTE é over_90_itemsque seleciona todos os itens com preço maior ou igual a US$ 90. O segundo CTE é london2_over_90que seleciona a quantidade vendida por London-2 para cada item incluído em over_90_items. Essa consulta tem um CTE aninhado - observe o FROM no segundo CTE referindo-se ao primeiro. Usamos LEFT JOIN sales porque London-2 pode não ter vendido todos os itens em over_90_items. O resultado da consulta é: itemunit_pricetotal_sold Cell Phone X11000 Cell Phone X21200 Cell Phone B2907 Antes de ir para a próxima seção, tenho alguns artigos para sugerir sobre expressões de tabela comuns. Tanto o "SQL CTEs Explained with Examples" quanto o "Where Can I Find Good SQL CTE Exercises?" têm muitos exemplos e exercícios. Consultas Recursivas e expressões comuns de tabela Em bancos de dados relacionais, é comum ter tabelas que representam hierarquias de dados, como funcionário-gerente, parte-subparte ou pai-filho. Para percorrer essas hierarquias em qualquer direção (de cima para baixo ou de baixo para cima), os bancos de dados usam uma construção chamada CTEs recursivos. RECURSIVE é uma palavra reservada para definir um CTE para percorrer uma estrutura de dados recursiva. A forma da consulta recursiva é a seguinte: WITH RECURSIVE cte_name AS ( CTE_query_definition -- non recursive query term UNION ALL CTE_query_definition -- recursive query term ) SELECT * FROM cte_name; As consultas recursivas estão fora do escopo deste artigo introdutório, mas tenho três outras sugestões para quem quiser saber mais sobre o assunto: "How to Organize SQL Queries with CTEs", "Doit in SQL: Recursive SQL Tree Traversal" e "Get to Know the Power of SQL Consultas Recursivas." Eles explicam detalhadamente as consultas recursivas com muitos exemplos. As CTEs do SQL são um recurso poderoso As expressões de tabela comuns são um recurso poderoso da linguagem SQL. Elas nos permitem criar consultas mais legíveis e gerenciar as diferenças de formato entre os dados da tabela e os dados do relatório. Neste artigo, abordamos o que é um CTE e como usá-lo em diferentes tipos de consultas. Também mencionamos que os CTEs podem ser usados em consultas recursivas. Recomendo o curso Consultas Recursivas em LearnSQL.com.brno qual você aprende interativamente a trabalhar com expressões de tabela comuns em SQL. Você também aprenderá a processar estruturas de dados recursivas, como gráficos e árvores em SQL, usando CTEs recursivos. Além disso, confira a trilha SQL Avançadoem que você vai além dos conceitos básicos para se tornar um mestre em SQL. Se você precisar se preparar para uma entrevista sobre SQL, há um artigo interessante, "Top 5 SQL CTE Interview Questions", que discute expressões de tabela comuns sob outra perspectiva. Se você aprendeu a usar CTEs, está um passo à frente no caminho para se tornar um desenvolvedor de SQL. Continue crescendo! Tags: sql aprender sql cte