Olá! Seja bem-vindo!

Hoje veremos como usar o PIVOT com SOMATÓRIA de COLUNAS e LINHAS, uma técnica complementar as que vimos nos vídeos anteriores sobre esse assunto (SELECT com PIVOT).

 

 

O que aprendemos até agora

Esse assunto deu o que falar, certo? Esse é o quarto vídeo da série sobre PIVOT, então estou incluindo os links aqui nesse artigo para que você tenha tudo em um só local:

 

Como transformar linhas em colunas

No primeiro vídeo de nossa série te mostrei a sintaxe básica do PIVOT: https://dba-pro.com/como-transformar-linhas-em-colunas-no-sql-server

 

Como executar PIVOT com colunas dinâmicas

No segundo vídeo, te mostrei como trabalhar com PIVOT em um cenário de colunas dinâmicas, assim você não precisa alterar sua query a cada mudança de informações na base (ex: ano ou nomes de colaboradores): https://dba-pro.com/pivot-com-colunas-dinamicas-no-sql-server/

 

 

Como executar PIVOT com somatório das colunas

No terceiro vídeo te mostrei como criar um somatório nas colunas PIVOTEADAS: https://dba-pro.com/pivot-com-somatoria-das-colunas-no-sql

 

PIVOT com SOMATÓRIA de COLUNAS e LINHAS

Atendendo a pedidos dos alunos, hoje iremos para o próximo passo. Além de fazermos a somatória das colunas, para termos o montante vendido ano a ano, montaremos também um somatório das linhas, para sabermos de forma simplificada o quanto cada colaborador vendeu no total.

 

Aqui vai o script da aula:

 


------------------------------------------------------------------
-- PIVOT: Transposição (PIVOT) + Totalizadores de colunas e linhas (GROUPING SETS)
------------------------------------------------------------------
--------------------------------------------------
-- 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'),
	('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 + Somatória -------------------------------------------------- -- Transposição simples: 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 ([2013], [2014], [2015], [2016], [2017], [2018])) em_colunas order by 1 go -- Transposição com somatória de colunas - referências: módulo 3 vídeos 12 (agrupamentos) e 17 (transposição) -- 1) Coalesce da coluna NOME para incluir o total por ano -- 2) Trocar group by por grouping sets e adicionar uma somatória por ano select * from ( select year(dt) as Ano, coalesce(c.nm, 'TOTAIS DO ANO =>') as Colaborador,
		sum(vl_venda) as Valor
	from vendas 
	join colaboradores c on c.id = vendas.id_vendedor
	--group by c.nm, year(dt) -- substituimos group by por grouping sets
	group by grouping sets (
		(c.nm, year(dt)), -- agrupamento padrão (igual ao group by)
		(year(dt)) -- somatória por ano
		) 
) em_linha
pivot (sum(valor) for ano in ([2013], [2014], [2015], [2016], [2017], [2018])) em_colunas 
order by 1
go


-- Transposição com somatória de colunas / linhas / total geral: Referência Módulo 3 (aulas 12 e 17)
-- 1) Coalesce no ano
-- 2) Adicionar somatórias "por nome" e "total geral" ao grouping sets
-- 3) Incluir coluna total do colaborador no pivot
select *
from (
	select 
		coalesce(cast(year(dt) as varchar(50)), 'TOTAL DO COLABORADOR') as Ano,
		coalesce(c.nm, 'TOTAL DO ANO =>') as Colaborador,
		sum(vl_venda) as Valor
	from vendas 
	join colaboradores c on c.id = vendas.id_vendedor
	group by grouping sets (
		(c.nm, year(dt)),
		(year(dt)),
		(c.nm),
		()
		) 
) em_linha
pivot (sum(valor) for ano in ([2013], [2014], [2015], [2016], [2017], [2018], [TOTAL DO COLABORADOR])) em_colunas 
order by 1
go

--------------------------------------------------
-- Excluindo dados de teste
--------------------------------------------------
use master
drop database curso

 

CONCLUSÃO

Se você já está em meu curso de SQL sabe o quanto eu gosto de misturar os assuntos, e essa série sobre PIVOT foi providencial para isso, concorda? Vimos SELECT, CTE, JOINS, cláusula XML, string functions, PIVOT e agora GROUPING SETS, somando tanto colunas, quanto linhas.

 

Espero que você também tenha achado esses conteúdos simples, divertidos e úteis.

 

Abraço do seu amigo Josué 🙂

Deixe um comentário

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