DEV Community

Cover image for Gerando um totalizador acumulado por linha sem usar cursor.
Allan Rodrigues
Allan Rodrigues

Posted on

Gerando um totalizador acumulado por linha sem usar cursor.

Olá pessoas!!!
Acredito que assim como eu vocês já se depararam com situações nas quais precisavam gerar um total que vai se acumulando linha a linha, não é mesmo?
E quando geramos consultas pra relatórios acabamos usando o famoso cursor para gerar esses totalizadores, o que acaba não sendo tão performático assim.
Dessa forma resolvi mostrar aqui como podemos gerar esse tipo de totalizador usando Window Function, no T-SQL.

Pra montar esse exemplo eu usei:

  1. SQL SERVER 2016 Developer
  2. SSMS
  3. Banco de dados de estudo WorldWideImporters

Antes de metermos a mão na massa, vocês tão ligados do que são as Window Function?
Window Function são funções nas quais podemos utilizar para realizar cálculos ou agregações em um conjunto de linhas que possuem alguma relação, nesse caso não precisamos utilizar o GROUP BY. E torna muito útil pois na mesma consulta podemos ter um resultado analítico e sintético. A sua utilização é bem simples.

Nesse Link da documentação da Microsoft tem um detalhamento melhor sobre Window Function. Pois não é o caso aqui entrar em muito detalhe apenas vamos abordar um caso específico, lá você pode abrir a sua mente e viajar em possíveis soluções...

Hora de botar a mão na massa!!!!

No cenário em questão vamos imaginar que foi feito uma solicitação para você gerar uma consulta que mostre o ID do pedido, ID do Cliente, Data do Pedido, Descrição do pedido, Quantidade, Valor Unitário, Total Geral do pedido e um Total Acumulativo por pedido.
Abaixo nos tempos os Script para atender essa solicitação.

Alt Text

Na linha na qual geramos o total geral:
SUM(OL.UnitPrice * Quantity) OVER(PARTITION BY OL.OrderId) AS Total

Usamos a Window Function OVER() gerando uma partição com o PARTITION BY e com isso podemos somar os registros referente a um determinado ID sem precisar usar o GROUP BY.

Na linha na qual geramos o total corrente:
SUM(OL.UnitPrice * Quantity) OVER(PARTITION BY OL.OrderID ORDER BY OL.OrderID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS Total_Corrente

De forma semelhante ao total geral também criamos uma partição com o PARTITION BY para ele gerar o total corrente por ID do pedido, porém acrescentamos um ORDER BY que é obrigatório quando utilizamos UNBOUNDED PRECEDING.

UNBOUNDED PRECEDING indica que a Window Function irá começar da primeira linha da partição.

CURRENTE ROW indica que é até a linha corrente.

Então ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, seria as lihas entre o início da partição e a linha corrente. Com isso podemos ir gerando o total por linha da partição.

Abaixo o resultado da nossa consulta.

Alt Text

Então é isso pessoal, espero que isso seja útil pra vocês. :D

Top comments (0)