Database
 sql >> Base de Dados >  >> RDS >> Database

Entendendo o Operador Pivot no SQL


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.
  1. 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".
  2. 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.
  3. 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