Sintaxe PIVOT de fornecedores e de tabela cruzada
PIVOT do SQL Server e crosstab do Postgres, além das limitações de cada um.
Sintaxe PIVOT de fornecedores e de tabela cruzada é uma aula grátis de SQL Interview Prep no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Interview Prep inclui 4 aulas no total.
Além da agregação condicional
Você já conhece a tabela dinâmica portátil com CASE. Mas os entrevistadores também querem saber se você consegue usar operadores de tabela dinâmica específicos de cada fornecedor quando eles estão disponíveis.
O SQL Server inclui um operador PIVOT dedicado. O PostgreSQL oferece uma função crosstab na extensão tablefunc. Conhecer ambos e suas armadilhas demonstra experiência prática.
Anatomia do PIVOT do SQL Server
O PIVOT do SQL Server recebe três elementos:
- Uma agregação sobre a coluna de valores.
- Uma cláusula
FORque nomeia a coluna cujos valores se tornarão novas colunas. - Uma lista
INdos valores literais que serão transformados em colunas.
Ele precisa ser aplicado a uma tabela derivada que exponha exatamente a chave, a coluna de expansão e o valor, sem nada mais.
SELECT region, [Q1], [Q2]
FROM (SELECT region, quarter, amount FROM sales) AS src
PIVOT (
SUM(amount)
FOR quarter IN ([Q1], [Q2])
) AS p;O GROUP BY implícito
Uma armadilha sutil do PIVOT que os entrevistadores testam é que o agrupamento é implícito. O SQL Server agrupa por todas as colunas da fonte que não correspondem à coluna agregada nem à coluna FOR.
Portanto, se a sua tabela derivada incluir acidentalmente uma coluna extra, como order_id, a tabela dinâmica também fará o agrupamento por ela, e você obterá muito mais linhas do que o esperado. Sempre reduza a consulta interna a apenas chave, expansão e valor.
-- WRONG: order_id leaks in and breaks grouping
FROM (SELECT region, quarter, amount, order_id FROM sales) AS src
PIVOT (SUM(amount) FOR quarter IN ([Q1],[Q2])) AS p;
-- The pivot now groups by region AND order_idNomes de coluna entre colchetes
No SQL Server, os nomes das colunas transformadas em tabela dinâmica são os valores literais dos dados, envolvidos em colchetes. Se um valor começar com um dígito ou contiver espaços, os colchetes serão obrigatórios.
Você os seleciona usando o mesmo nome entre colchetes no SELECT externo. É também por isso que PIVOT não consegue lidar com valores desconhecidos sem SQL dinâmico: a lista IN é fixada no código.
SELECT region, [2023], [2024]
FROM (SELECT region, yr, amount FROM sales) AS s
PIVOT (SUM(amount) FOR yr IN ([2023], [2024])) AS p;Tabela cruzada do PostgreSQL
O PostgreSQL não tem a palavra-chave PIVOT. Em vez disso, a extensão tablefunc fornece crosstab, uma função que recebe uma string SQL e remodela sua saída.
Você precisa habilitar a extensão primeiro. crosstab espera que a consulta de origem retorne exatamente três colunas: identificador da linha, categoria e valor, nessa ordem.
CREATE EXTENSION IF NOT EXISTS tablefunc;
SELECT *
FROM crosstab(
'SELECT region, quarter, amount FROM sales ORDER BY 1, 2'
) AS ct(region text, q1 numeric, q2 numeric);A lista de definição de colunas
A parte mais propensa a erros do crosstab é a lista de definição de colunas AS ct(...) no final. Você precisa declarar por conta própria os nomes e tipos das colunas de saída, e eles devem corresponder ao número e à ordem das categorias.
Se uma categoria estiver ausente em uma linha, a tabela cruzada a preencherá conforme a posição, o que pode desalinhá-la, a menos que você use a forma com dois argumentos apresentada abaixo.
SELECT *
FROM crosstab(
'SELECT region, quarter, amount FROM sales ORDER BY 1, 2'
) AS ct(region text, q1 numeric, q2 numeric);
-- ct(...) MUST list every output column and its typecrosstab com dois argumentos
Para evitar desalinhamentos quando algumas linhas não tiverem determinadas categorias, use a forma com dois argumentos. A segunda consulta retorna a lista completa e ordenada de valores de categoria, para que a tabela cruzada saiba exatamente em qual coluna cada valor deve ficar.
Essa é a forma robusta esperada pelos entrevistadores quando as categorias são esparsas.
SELECT *
FROM crosstab(
'SELECT region, quarter, amount FROM sales ORDER BY 1, 2',
'SELECT DISTINCT quarter FROM sales ORDER BY 1'
) AS ct(region text, q1 numeric, q2 numeric);O MySQL não tem nenhum dos dois
Se o entrevistador perguntar sobre MySQL, a resposta é direta: MySQL não tem PIVOT nem tabela cruzada. A única opção é usar agregação condicional com CASE (ou a forma abreviada SUM(... ) + IF()).
É exatamente por isso que o padrão portátil com CASE é tão valorizado: ele é a alternativa básica que funciona em todos os mecanismos.
-- MySQL: only conditional aggregation works
SELECT
region,
SUM(IF(quarter = 'Q1', amount, 0)) AS q1,
SUM(IF(quarter = 'Q2', amount, 0)) AS q2
FROM sales
GROUP BY region;Exemplo prático: contagens de status no SQL Server
Uma solicitação de relatório: uma linha por região, com uma coluna contando os pedidos em cada status. No SQL Server, forneça ao PIVOT uma tabela derivada enxuta usando COUNT.
Como você conta a própria coluna de status, toda linha de status não NULL em um grupo é contabilizada. O SELECT externo lista cada status como uma coluna entre colchetes. Essa é a alternativa concisa para escrever três expressões COUNT(CASE ...).
SELECT region, [pending], [shipped], [delivered]
FROM (SELECT region, status FROM orders) AS src
PIVOT (
COUNT(status)
FOR status IN ([pending], [shipped], [delivered])
) AS p;Limitações compartilhadas
PIVOT e a tabela cruzada compartilham a mesma limitação básica da agregação condicional: as colunas de saída precisam ser conhecidas quando você escreve a consulta.
- SQL Server: a lista
INé literal. - Tabela cruzada do PostgreSQL: a lista de definição de colunas é literal.
Nenhuma das duas consegue descobrir categorias em tempo de execução. Isso requer a construção dinâmica da string SQL.
Qual você deve usar
Uma boa resposta em uma entrevista compara as opções com honestidade:
- Agregação com CASE: portável, legível e funciona em todos os mecanismos. É a escolha padrão.
- PIVOT do SQL Server: conciso para muitas colunas, mas o agrupamento implícito surpreende algumas pessoas.
- Tabela cruzada do PostgreSQL: poderosa, mas verbosa; requer uma extensão e uma lista de definição de colunas.
Quando estiver em dúvida, prefira a agregação condicional e mencione os operadores dos fornecedores como alternativas.
Verificação rápida
Esclareça o comportamento do PIVOT do SQL Server que os entrevistadores costumam investigar.
Recapitulação
Sintaxe de PIVOT dos fornecedores em uma tela:
- SQL Server:
PIVOT (SUM(x) FOR col IN ([a],[b])), com um GROUP BY implícito sobre as colunas restantes. - PostgreSQL:
crosstab()detablefunc, exigindo uma lista de definição de colunas; use a forma com dois argumentos para dados esparsos. - MySQL: nenhum dos dois existe; use
CASE. - Os três exigem que as colunas sejam conhecidas no momento em que a consulta é escrita.
Perguntas Frequentes
A aula “Sintaxe PIVOT de fornecedores e de tabela cruzada” é grátis?
Sim — o texto completo de “Sintaxe PIVOT de fornecedores e de tabela cruzada” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Interview Prep, atualize para CoddyKit PRO. O curso de SQL Interview Prep inclui 4 aulas no total.
O que vou aprender em “Sintaxe PIVOT de fornecedores e de tabela cruzada”?
PIVOT do SQL Server e crosstab do Postgres, além das limitações de cada um. Você pratica SQL Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar SQL Interview Prep?
Nenhuma experiência prévia é necessária. SQL Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “Sintaxe PIVOT de fornecedores e de tabela cruzada”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de SQL Interview Prep?
Sim. Cada aula de SQL Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Transformação com agregação condicional
- Sintaxe PIVOT de fornecedores e de tabela cruzada
- Transformando colunas em linhas
- PIVOTs dinâmicos com colunas desconhecidas