Oi! Seja bem-vindo!

Hoje veremos como TRANSFORMAR LINHAS em COLUNAS no SQL Server usando o PIVOT, esse comando simples que te ajudará a criar relatórios e gráficos fantásticos em um passe de mágica!

Em minha experiência esse tipo de conhecimento é vital para a sua carreira, porque demonstrar informações complexas de forma simples, para que gestores possam facilmente decidir a respeito, é uma habilidade que dá muito dinheiro e destaque profissional.

O que é PIVOT?

O comando PIVOT simplifica enormemente o trabalho de converter linhas de um resultado em colunas.

Muitas vezes quando apresento esse recurso sou questionado: “Mas para que vou querer fazer isso?”.

Em meu ponto de vista a maior utilização é quando você quer criar relatórios sintéticos ou organizar dados para uma apresentação. Veja no exemplo que mostrei no vídeo, no resultset abaixo, a visualização das informações é precária para dizer o mínimo. Colocar isso em um powerpoint é simplesmente inviável:

Ano Colaborador Valor
2013 Abismail do Rosário 2271700.00
2013 Chaves Rosembaum 2251600.00
2013 Francisco Sanguessuga 2052300.00
2013 Josemar Pinto Godinho 2226500.00
2013 Navegador da Luz 1858000.00
2013 Necrotério Silveira 2251500.00
2013 Rolando da Rocha 2422100.00
2014 Abismail do Rosário 2263700.00
2014 Chaves Rosembaum 2129200.00
2014 Francisco Sanguessuga 2521500.00
2014 Josemar Pinto Godinho 2239900.00
2014 Navegador da Luz 2197400.00
2014 Necrotério Silveira 2399100.00
2014 Rolando da Rocha 2164300.00
2015 Abismail do Rosário 2044400.00
2015 Chaves Rosembaum 2386200.00
2015 Francisco Sanguessuga 2600800.00
2015 Josemar Pinto Godinho 2096500.00
2015 Navegador da Luz 2341900.00
2015 Necrotério Silveira 2308600.00
2015 Rolando da Rocha 2121100.00
2016 Abismail do Rosário 2285200.00
2016 Chaves Rosembaum 2390200.00
2016 Francisco Sanguessuga 2212900.00
2016 Josemar Pinto Godinho 2152300.00
2016 Navegador da Luz 1907800.00
2016 Necrotério Silveira 2630400.00
2016 Rolando da Rocha 1840900.00
2017 Abismail do Rosário 2474300.00
2017 Chaves Rosembaum 2243200.00
2017 Francisco Sanguessuga 2263900.00
2017 Josemar Pinto Godinho 2445400.00
2017 Navegador da Luz 2152100.00
2017 Necrotério Silveira 2358500.00
2017 Rolando da Rocha 2287600.00
2018 Abismail do Rosário 33500.00
2018 Chaves Rosembaum 71500.00
2018 Francisco Sanguessuga 43200.00
2018 Josemar Pinto Godinho 85300.00
2018 Navegador da Luz 74300.00
2018 Necrotério Silveira 59400.00
2018 Rolando da Rocha 65800.00

Agora se gruparmos os resultados de venda dos anos em colunas, então temos algo muito interessante, fácil de explicar e incluir rapidamente em uma apresentação:

Colaborador 2013 2014 2015 2016 2017 2018
Abismail do Rosário 2271700.00 2263700.00 2044400.00 2285200.00 2474300.00 33500.00
Chaves Rosembaum 2251600.00 2129200.00 2386200.00 2390200.00 2243200.00 71500.00
Francisco Sanguessuga 2052300.00 2521500.00 2600800.00 2212900.00 2263900.00 43200.00
Josemar Pinto Godinho 2226500.00 2239900.00 2096500.00 2152300.00 2445400.00 85300.00
Navegador da Luz 1858000.00 2197400.00 2341900.00 1907800.00 2152100.00 74300.00
Necrotério Silveira 2251500.00 2399100.00 2308600.00 2630400.00 2358500.00 59400.00
Rolando da Rocha 2422100.00 2164300.00 2121100.00 1840900.00 2287600.00 65800.00

Naturalmente, para fazer um gráfico também fica muito mais fácil usando um resultset como esse.

Como transformar Linhas em Colunas no SQL Server

Abaixo o script que utilizei no vídeo:


------------------------------------------------------------------
-- PIVOT: Transposição (linhas para colunas)
------------------------------------------------------------------
--------------------------------------------------
-- Banco de dados para nosso teste
--------------------------------------------------
-- Banco de testes
use master
if db_id('curso') is not null 
	drop database curso
go
create database curso
go
use curso
go
create table colaboradores (
	id smallint identity(1,1) primary key,
	nm varchar(100) not null,
)
insert into colaboradores values 
	('Abismail do Rosário'),
	('Josemar Pinto Godinho'),
	('Francisco Sanguessuga'),
	('Rolando da Rocha'),
	('Chaves Rosembaum'),
	('Necrotério Silveira'),
	('Navegador da Luz')

create table produtos (
	id smallint identity(1,1) primary key,
	nm varchar(100),
	vl decimal(10,2),
	ic_ativo bit not null default (1)
)
insert produtos (nm, vl) values 
	('Mouse Gammer 25 botões', 200),
	('Teclado Gammer 350 teclas', 300),
	('Monitor 32 Pol Full HD', 1000),
	('RAM DDR4 4GB Powerturbo', 500),
	('CPU Nasa 10Ghz', 2000),
	('HD SSD 1TB', 2000)

create table vendas (
	id int not null identity(1, 1) primary key,
	dt datetime not null,
	id_produto smallint not null foreign key references produtos(id),
	id_vendedor smallint foreign key references colaboradores(id),
	qt int check (qt > 0),
	vl_unitario decimal (10,2), 
	vl_venda as qt * vl_unitario
)
;with cte_seq as (
	select 1 as nr_cont
	union all
	select nr_cont + 1 
	from cte_seq where nr_cont < 10000) insert into vendas (dt, id_produto, id_vendedor, qt, vl_unitario) select dateadd(day, -(abs(checksum(newid())) % 1825), getdate()) dt, produto.id, colaborador.id, 1 + (abs(checksum(newid())) % 15) nr_quantidade, produto.vl vl_unitario from cte_seq left join (select top 1 id, vl from produtos order by newid()) produto on 1=1 left join (select top 1 id from colaboradores order by newid()) colaborador on 1=1 option (maxrecursion 0) go -------------------------------------------------- -- Transposição: de linhas para colunas -------------------------------------------------- -- Consulta padrão select year(dt) as Ano, c.nm as Colaborador, sum(vl_venda) as Valor from vendas join colaboradores c on c.id = vendas.id_vendedor group by c.nm, year(dt) -- PIVOT: Anos -> colunas:
select *
from (
	select 
		year(dt) as Ano,
		c.nm as Colaborador,
		sum(vl_venda) as Valor
	from vendas 
	join colaboradores c on c.id = vendas.id_vendedor
	group by c.nm, year(dt)
) em_linha
pivot (sum(valor) for ano in ([2012], [2013], [2014], [2015], [2016], [2017])) em_colunas 
order by 1
go

-- PIVOT: Colaboradores -> colunas:
select *
from (
	select 
		year(dt) as Ano,
		c.nm as Colaborador,
		sum(vl_venda) as Valor
	from vendas 
	join colaboradores c on c.id = vendas.id_vendedor
	group by c.nm, year(dt)
) em_linha
pivot (sum(valor) for colaborador in ([Abismail do Rosário], [Chaves Rosembaum], [Francisco Sanguessuga])) em_colunas 
order by 1
go


--------------------------------------------------
-- Excluindo dados de teste
--------------------------------------------------
use master
drop database curso
<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>

 

CONCLUSÃO

Como você viu, converter linhas para colunas é muito, mas muito fácil. As vezes fico empolgado com esse assunto pois sou do tempo que não existia o PIVOT… nem queira saber a trabalheira que dava fazer esse tipo de coisa.

Fico feliz que o SQL segue melhorando, e cada dia mais nós DBAs podemos trabalhar no que importa para o negócio ao invés de perder horas e horas com trabalho braçal

Espero que tenha gostado do artigo, nos vemos no próximo!

Abraço do seu amigo Josué 🙂

 

4 respostas

  1. Bom dia! Obrigada por compartilhar isso conosco. Eu usei o pivot em um dos meus relatórios, porém, estou com dificuldade para trazer as informações em uma linha só. Ele está trazendo um bloco para cada mês, não estou conseguindo trazer apenas um bloco para todos.

    1. Oi Elayne, entendo ser o o comportamento esperado, a não ser que agregue os valores de todos os meses com alguma função como “sum”. Abs Josué

  2. Parabéns pela postagem, bem explicado.

    Agora gostaria de saber se existe a possibilidade que realizar um Pivot Dinâmico dentro de uma View?

    1. Oi Antônio, obrigado pelo seu feedback, fico feliz que tenha gostado! Seria ótimo encapsularmos esse código em um objeto usável em SELECTs (views ou funções)… porém views aceitam apenas um comando por objeto, e funções não permitem “side-effect operators”, como o comando “execute”.

      Ou seja, para resolver esse tipo de caso, você precisará de uma Stored Procedure ou uma CLR.

      Abraço, Josué

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *