O operador pivô no SQL Server converte cada linha no conjunto de resultados agregados em colunas correspondentes no conjunto de saída. O operador pivô é particularmente útil para escrever consultas de tabulação cruzada.
Vejamos como isso funciona na prática.
Preparando os dados
Primeiro, vamos criar alguns dados fictícios que podemos usar para implementar o operador pivô.
CREATE DATABASE schooldb
CREATE TABLE student
(
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
gender VARCHAR(50) NOT NULL,
DOB datetime NOT NULL,
total_score INT NOT NULL,
city VARCHAR(50) NOT NULL
)
INSERT INTO student
VALUES (1, 'Jolly', 'Female', '12-JUN-1989', 500, 'London'),
(2, 'Jon', 'Male', '02-FEB-1974', 545, 'Manchester'),
(3, 'Sara', 'Female', '07-MAR-1988', 600, 'Leeds'),
(4, 'Laura', 'Female', '22-DEC-1981', 400, 'Liverpool'),
(5, 'Alan', 'Male', '29-JUL-1993', 500, 'London'),
(6, 'Kate', 'Female', '03-JAN-1985', 500, 'Liverpool'),
(7, 'Joseph', 'Male', '09-APR-1982', 643, 'London'),
(8, 'Mice', 'Male', '16-AUG-1974', 543, 'Liverpool'),
(9, 'Wise', 'Male', '11-NOV-1987', 499, 'Manchester'),
(10, 'Elis', 'Female', '28-OCT-1990', 400, 'Leeds');
Como funciona o operador de pivô?
A maneira padrão de agrupar dados SQL é usando a cláusula Group By. Vamos criar uma consulta que calcule a média dos valores na coluna total_score da tabela do aluno, agrupados por cidade.
USE schooldb
SELECT
city,
AVG(total_score) as Avg_Score
FROM
student
GROUP BY
city
Isso dá o seguinte resultado:
[ID da tabela=25 /]
E se quisermos um conjunto de resultados onde os nomes das cidades são exibidos em colunas onde cada coluna contém o valor médio do total_score dos alunos pertencentes a essa cidade? Algo assim:
[ID da tabela=26 /]
É aqui que o operador pivô é útil.
Selecionando os dados básicos
A primeira etapa ao usar o operador pivô é selecionar os dados básicos nos quais o operador pivô será baseado. Queremos agrupar nossos dados por cidade e encontrar a média do total_score dos alunos que pertencem a essa cidade. Portanto, precisamos escrever uma instrução SELECT simples que selecione a cidade e o total_score.
SELECT
city,
total_score
FROM
student
Criando um conjunto de dados temporário
Agora, idealmente, poderíamos aplicar diretamente o operador pivô nos dados de base que criamos na seção anterior, mas infelizmente não podemos. Para que o operador pivô funcione, temos que criar uma expressão com valor de tabela à qual podemos aplicar o operador pivô. Temos uma variedade de opções aqui; podemos usar tabelas derivadas, expressões de tabela comum (CTEs) ou podemos até criar tabelas temporárias.
Para este exemplo, usaremos uma tabela derivada rápida e simples. Para fazer isso com a instrução select básica que criamos na última seção, nós a envolvemos em um conjunto de parênteses e então aplicamos um alias a ela. Por fim, selecionamos tudo dessa tabela derivada.
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
Aplicando o Operador de Pivô
Agora que preparamos nossos dados de base e criamos uma tabela derivada, aplicaremos o operador pivô a ela.
Para fazer isso, insira “PIVOT” no final da tabela derivada, seguido por um conjunto de parênteses e dê um alias a essa tabela dinâmica.
Dentro dos parênteses, temos que especificar algumas informações importantes.
- Precisamos especificar o campo ao qual queremos aplicar uma função de agregação. No nosso caso, queremos aplicar a função agregada do AVG na coluna "total_score".
- Depois, temos que dizer em quais colunas dos dados de base estamos dinamizando nossos dados. Fazemos isso escrevendo “FOR” seguido do nome da coluna que é uma cidade em nosso exemplo.
- A etapa final é um pouco irritante. Temos que listar os valores da coluna da cidade que queremos que se tornem títulos em nossa tabela dinâmica. Usamos o operador IN seguido por um conjunto de parênteses. Dentro dos parênteses, usamos uma lista separada por vírgulas onde escrevemos o nome de cada coluna dentro de um colchete. Em nosso exemplo, queremos Londres, Leeds e Manchester como os nomes dos cabeçalhos da tabela dinâmica e os escrevemos neste formato:([London], [Leeds], [Manchester]).
USE schooldb
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
PIVOT(
AVG(total_score)
FOR city IN ([London],[Liverpool],[Leeds],[Manchester])
) AS StudentPivotTable
Se você executar a consulta acima, os resultados ficarão assim:
[ID da tabela=27 /]
Adicionando grupos de linhas na tabela dinâmica
Nas seções anteriores, vimos como converter grupos de linhas em grupos de colunas usando o operador pivô. No entanto, você também pode adicionar grupos de linhas junto com grupos de colunas em uma tabela dinâmica.
Por exemplo, se você quiser encontrar o valor médio da coluna total_score de todos os alunos agrupados por cidade e gênero, você pode usar o grupo de colunas e o grupo de linhas em conjunto dentro de uma tabela dinâmica. Aqui, cada coluna representará um nome de cidade e cada linha representará um gênero de estudante.
Felizmente, você não precisa escrever nenhum script adicional para adicionar grupos de linhas a uma tabela dinâmica. Dentro do conjunto de dados base, basta adicionar o nome da coluna que você deseja adicionar como um grupo de linhas à tabela dinâmica.
USE schooldb
SELECT * FROM
(SELECT
city,
gender,
total_score
FROM
student
)
AS StudentTable
PIVOT(
AVG(total_score)
FOR city IN ([London],[Liverpool],[Leeds],[Manchester])
) AS StudentPivotTable
No script acima, simplesmente adicionamos a coluna “gender” na instrução SELECT base.
A saída da consulta acima é assim:
[ID da tabela=28 /]
Isso é tabulação cruzada. Por exemplo, pode-se ver pelos resultados que a pontuação total média de estudantes do sexo feminino que vivem em Londres é 500. Da mesma forma, a pontuação total média dos estudantes do sexo masculino que vivem em Londres é de 571.
Leia também:
Criando uma tabela dinâmica dinâmica com a função QUOTENAME