Este é um trecho de código na página do MSDN para a cláusula OVER:
USE AdventureWorks2012;
GO
SELECT BusinessEntityID, TerritoryID
,DATEPART(yy,ModifiedDate) AS SalesYear
,CONVERT(varchar(20),SalesYTD,1) AS SalesYTD
,CONVERT(varchar(20),AVG(SalesYTD) OVER (PARTITION BY TerritoryID
ORDER BY DATEPART(yy,ModifiedDate)
),1) AS MovingAvg
,CONVERT(varchar(20),SUM(SalesYTD) OVER (PARTITION BY TerritoryID
ORDER BY DATEPART(yy,ModifiedDate)
),1) AS CumulativeTotal
FROM Sales.SalesPerson
WHERE TerritoryID IS NULL OR TerritoryID < 5
ORDER BY TerritoryID,SalesYear;
Portanto, estou tendo problemas para entender por que a função CONVERT teve que ser usada lá. Presumo que tenha a ver com os tipos de retorno de um dos campos na parte da expressão da função de conversão? O CAST pode ser usado em vez disso? A segunda pergunta que tenho é: como exatamente essa parte funciona?
SUM(SalesYTD) OVER (PARTITION BY TerritoryID
ORDER BY DATEPART(yy,ModifiedDate)
O que exatamente isso está dizendo? É uma soma calculada para cada ano? É isso?
Se o tipo SalesYTD for flutuante ou real:
1 = Sempre 8 dígitos. Use sempre em notação científica.
Se o tipo for dinheiro e dinheiro pequeno:
1 = Vírgulas a cada três dígitos à esquerda da vírgula e dois dígitos à direita da vírgula; por exemplo, 3.510,92.
Se o tipo SalesYTD for flutuante ou real:
0 (padrão) = Um máximo de 6 dígitos. Use em notação científica, quando apropriado.
Se o tipo for dinheiro e dinheiro pequeno:
0 (padrão) = Sem vírgulas a cada três dígitos à esquerda do ponto decimal e dois dígitos à direita do ponto decimal; por exemplo, 4235.98.
Existem outras diferenças e valores padrão para estilo com outros tipos, mas acho que abrange seus tipos de dados. Consulte CAST e CONVERT (Transact-SQL)
Para cada partição (=TerritoryID), são necessários todos os SalesYTD, ordene-os por DATEPART(yy,ModifiedDate) e some-os. Observe que a parte do pedido não é necessária ou pode ser qualquer coisa, pois você apenas faz SUM e AVG, mas ao usá-la altera os comportamentos (consulte a resposta do hipercubo sobre isso e a média móvel). Com ROW_NUMBER e outros, seria importante e obrigatório.
Diferença entre SUM e SUM em movimento (resposta @hypercube):
Resultado:
Consulte Cláusula OVER (Transact-SQL) para funções de janela.
Em relação aos agregados de janela (
SUM()
eAVG()
comOVER (...)
:A cláusula da página MSDN
OVER
(Transact-SQL) tem esta observação (bastante oculta):o que significa que seu código acima tem os mesmos resultados que:
então o
SUM()
é calculado (para uma linha) obtendo todas as linhas que têm o mesmoTerritoryID
e a parte do anoModifiedDate
é menor ou igual à parte do ano da linha. Isso geralmente é chamado de " total cumulativo ", pois contém o total de todos os valores desde o valor inicial (ano mínimo no exemplo) até (todas as linhas) do valor atual (ano). O mesmo se aplica aoAVG()
cálculo (que costuma ser chamado de " média móvel ".Na coluna do banco de dados AdventureWorks, SalesYTD é o
MONEY
tipo, portanto, neste caso, useCONVERT
com style=1 significa:CAST e CONVERT (Transact-SQL)
E algumas palavras sobre
AVG()
eSUM()
usando comOVER(PARITION BY ... ORDER BY ...)
declaração.Aqui está o resultado do AdvetureWorks:
MovingAvg significa SalesYTD médio desde o início (na partição atual) até esta linha em ordem crescente de ano de SalesYear.
CumulativeTotal significa somar SalesYTD desde o início (na partição atual) para esta linha em ordem crescente de ano de SalesYear.