🧚 Ei! O Beekeeper Studio é uma GUI de banco de dados rápida, moderna e open source Baixar
7 de janeiro de 2026 Por Matthew Rathbone

Uma tabela dinâmica (pivot) transforma linhas em colunas: uma linha por grupo e uma coluna para cada valor de outro campo, como uma coluna por trimestre. Em SQL, você monta uma usando CASE dentro de uma agregação como SUM, agrupando pelo que cada linha deve representar. Os exemplos funcionam em PostgreSQL, MySQL, SQLite e SQL Server.

Como fazer uma tabela dinâmica em SQL

Escreva uma agregação para cada coluna de saída. O CASE dentro dela deixa passar só as linhas que pertencem àquela coluna, e o GROUP BY gera uma linha por grupo:

SELECT
  row_column,
  SUM(CASE WHEN pivot_column = 'value 1' THEN amount ELSE 0 END) AS value_1,
  SUM(CASE WHEN pivot_column = 'value 2' THEN amount ELSE 0 END) AS value_2
FROM table_name
GROUP BY row_column;

Aqui cada produto ganha uma linha, com as unidades de cada trimestre lado a lado:

-- Input: sales
-- product  | quarter | units
-- ---------+---------+------
-- Keyboard | Q1      | 120
-- Keyboard | Q2      | 95
-- Monitor  | Q1      | 40
-- Monitor  | Q2      | 55
-- Mouse    | Q2      | 210

SELECT
  product,
  SUM(CASE WHEN quarter = 'Q1' THEN units ELSE 0 END) AS q1,
  SUM(CASE WHEN quarter = 'Q2' THEN units ELSE 0 END) AS q2
FROM sales
GROUP BY product
ORDER BY product;

-- Output:
-- product  | q1  | q2
-- ---------+-----+----
-- Keyboard | 120 | 95
-- Monitor  | 40  | 55
-- Mouse    | 0   | 210

Regras importantes

  • Você mesmo nomeia cada coluna. O SQL não consegue criar colunas a partir dos dados, então um terceiro trimestre precisa de uma terceira linha com CASE. Se a lista de valores muda com frequência, monte a consulta no código da sua aplicação.
  • ELSE 0 serve só para SUM e contagens. Ele transforma uma combinação ausente em 0 em vez de NULL. Com AVG, MIN ou MAX, omita o ELSE, senão os zeros contam como valores reais:
-- Input: the sales table above

SELECT
  product,
  ROUND(AVG(CASE WHEN quarter = 'Q1' THEN units ELSE 0 END), 1) AS q1_else_0,
  ROUND(AVG(CASE WHEN quarter = 'Q1' THEN units END), 1) AS q1_no_else
FROM sales
GROUP BY product
ORDER BY product;

-- Output:
-- product  | q1_else_0 | q1_no_else
-- ---------+-----------+-----------
-- Keyboard | 60.0      | 120.0
-- Monitor  | 20.0      | 40.0
-- Mouse    | 0.0       | NULL

Sintaxe alternativa

Você também vai encontrar FILTER no PostgreSQL e no SQLite, e o operador PIVOT no SQL Server. Ambos deixam uma combinação ausente como NULL em vez de 0:

-- Input: the sales table above

-- PostgreSQL and SQLite
SELECT
  product,
  SUM(units) FILTER (WHERE quarter = 'Q1') AS q1,
  SUM(units) FILTER (WHERE quarter = 'Q2') AS q2
FROM sales
GROUP BY product
ORDER BY product;

-- SQL Server
SELECT product, [Q1] AS q1, [Q2] AS q2
FROM (SELECT product, quarter, units FROM sales) AS src
PIVOT (SUM(units) FOR quarter IN ([Q1], [Q2])) AS p
ORDER BY product;

-- Output:
-- product  | q1   | q2
-- ---------+------+----
-- Keyboard | 120  | 95
-- Monitor  | 40   | 55
-- Mouse    | NULL | 210

Em código MySQL é comum ver SUM(IF(quarter = 'Q1', units, 0)), uma forma mais curta de escrever a versão com CASE. A extensão tablefunc do PostgreSQL também tem a função crosstab(); veja como criar tabelas dinâmicas no PostgreSQL com crosstab().

Quando usar uma tabela dinâmica?

Use pivot quando uma lista de linhas ficaria mais fácil de ler como uma grade. Estes são os motivos mais comuns.

Comparar uma medida lado a lado

Coloque os valores que você quer comparar (dias, trimestres, regiões) lado a lado em uma linha, em vez de espalhados por uma lista longa.

Mostrar mais de uma medida por coluna

Cada coluna de saída é uma agregação própria, então você pode combiná-las: sessões e visualizações de página por dispositivo, ou pedidos e receita por canal.

Contar linhas em cada categoria

Para contar em vez de somar, some 1 para cada linha correspondente ou use COUNT(CASE WHEN ... THEN 1 END): o COUNT ignora os NULLs gerados pelas outras linhas. É assim que você obtém tarefas por status ou tickets por prioridade.

Transformar linhas chave-valor em colunas

Configurações e atributos de produtos costumam ser armazenados como uma linha por nome e valor. Fazer o pivot com MAX(CASE ...) gera uma linha por item, com uma coluna por atributo. O MAX funciona com texto e pega o único valor de cada grupo.

Exemplos reais de tabelas dinâmicas em SQL

Avaliação média de apps por plataforma

Omita o ELSE ao calcular médias, para que um app sem avaliações em uma plataforma mostre NULL em vez de uma nota enganosa:

-- Input: reviews
-- app      | platform | rating
-- ---------+----------+-------
-- Budgetly | iOS      | 5
-- Budgetly | iOS      | 4
-- Budgetly | Android  | 3
-- FitTrack | Android  | 4
-- FitTrack | Android  | 5

-- In SQL Server, AVG of an integer column drops the decimals: use rating * 1.0
SELECT
  app,
  ROUND(AVG(CASE WHEN platform = 'iOS' THEN rating END), 1) AS ios,
  ROUND(AVG(CASE WHEN platform = 'Android' THEN rating END), 1) AS android
FROM reviews
GROUP BY app
ORDER BY app;

-- Output:
-- app      | ios  | android
-- ---------+------+--------
-- Budgetly | 4.5  | 3.0
-- FitTrack | NULL | 4.5

Pedidos e vendas por canal em cada região

Duas medidas para cada canal, uma contagem de pedidos e um total:

-- Input: orders
-- id | region | channel | amount
-- ---+--------+---------+-------
-- 1  | North  | web     | 120.00
-- 2  | North  | store   | 80.00
-- 3  | North  | web     | 45.50
-- 4  | South  | store   | 210.00
-- 5  | South  | store   | 64.00

SELECT
  region,
  COUNT(CASE WHEN channel = 'web' THEN 1 END) AS web_orders,
  SUM(CASE WHEN channel = 'web' THEN amount ELSE 0 END) AS web_sales,
  COUNT(CASE WHEN channel = 'store' THEN 1 END) AS store_orders,
  SUM(CASE WHEN channel = 'store' THEN amount ELSE 0 END) AS store_sales
FROM orders
GROUP BY region
ORDER BY region;

-- Output:
-- region | web_orders | web_sales | store_orders | store_sales
-- -------+------------+-----------+--------------+------------
-- North  | 2          | 165.50    | 1            | 80.00
-- South  | 0          | 0         | 2            | 274.00

Tickets de suporte por atendente e prioridade

Uma contagem para cada prioridade, mais um total. O COUNT(*) continua contando todas as linhas do grupo:

-- Input: tickets
-- id | agent | priority
-- ---+-------+---------
-- 1  | Priya | urgent
-- 2  | Priya | normal
-- 3  | Marco | normal
-- 4  | Priya | normal
-- 5  | Marco | low

SELECT
  agent,
  COUNT(CASE WHEN priority = 'low' THEN 1 END) AS low,
  COUNT(CASE WHEN priority = 'normal' THEN 1 END) AS normal,
  COUNT(CASE WHEN priority = 'urgent' THEN 1 END) AS urgent,
  COUNT(*) AS total
FROM tickets
GROUP BY agent
ORDER BY agent;

-- Output:
-- agent | low | normal | urgent | total
-- ------+-----+--------+--------+------
-- Marco | 1   | 1      | 0      | 2
-- Priya | 0   | 2      | 1      | 3

Uma linha de configurações por usuário

Cada configuração é armazenada como um nome e um valor. Um usuário que nunca definiu uma recebe NULL naquela coluna:

-- Input: user_settings
-- user_id | setting  | value
-- --------+----------+--------------
-- 1       | theme    | dark
-- 1       | language | en
-- 2       | language | de
-- 2       | timezone | Europe/Berlin
-- 3       | theme    | light

SELECT
  user_id,
  MAX(CASE WHEN setting = 'theme' THEN value END) AS theme,
  MAX(CASE WHEN setting = 'language' THEN value END) AS language,
  MAX(CASE WHEN setting = 'timezone' THEN value END) AS timezone
FROM user_settings
GROUP BY user_id
ORDER BY user_id;

-- Output:
-- user_id | theme | language | timezone
-- --------+-------+----------+--------------
-- 1       | dark  | en       | NULL
-- 2       | NULL  | de       | Europe/Berlin
-- 3       | light | NULL     | NULL

Leitura complementar sobre tabelas dinâmicas

Neste blog:

Documentação oficial:

Beekeeper Studio é um cliente de banco de dados gratuito e open source

A melhor ferramenta de consultas e edição de SQL que já usei. Tem tudo o que preciso para gerenciar meu banco de dados. - ⭐⭐⭐⭐⭐ Mit

O Beekeeper Studio é rápido, intuitivo e fácil de usar. Ele suporta vários bancos de dados e funciona muito bem no Windows, Mac e Linux.

A versão do Beekeeper para Linux tem 100% dos recursos, sem atalhos e sem concessões.

O que os usuários dizem sobre o Beekeeper Studio

★★★★★
"O Beekeeper Studio substituiu completamente meu antigo fluxo de trabalho com SQL. É rápido, intuitivo e torna o trabalho com bancos de dados prazeroso de novo."
— Alex K., desenvolvedor de banco de dados
★★★★★
"Já testei muitas GUIs de banco de dados, mas o Beekeeper encontra o equilíbrio perfeito entre recursos e simplicidade. Simplesmente funciona."
— Sarah M., engenheira full stack

Pronto para melhorar seu fluxo de trabalho com SQL?

download Baixar grátis