Eu tenho esse código que resume a quantidade de um determinado item ( itemid
) e pelo código de data do produto ( proddte
).
select sum(qty), itemid, proddte
from testtable where ....
group by itemid, proddte
O que eu quero fazer é obter o total de todos, qty
independentemente de itemid/proddte
. Eu tentei:
select sum(qty), itemid, proddte, sum(qty) over() as grandtotal
from testtable
where ....
group by itemid, proddte
Mas diz que eu também deveria ter qty
na group by
cláusula. Se eu fiz isso, o resultado não será igual ao meu resultado esperado.
Não precisa absolutamente ser representado como uma coluna separada, com o mesmo valor em cada linha. Qualquer representação é aceita, desde que eu possa exibir o total geral.
fonte
GROUP BY ROLLUP((itemid,proddte))
produziria o mesmo resultado e poderia ser menos confuso.itemid
ie é equivalente aGROUP BY GROUPING SETS((),(itemid),(itemid,proddte))
GROUP BY ROLLUP(itemid,proddte)
, por outro lado, produziria subtotais (adicionais) emitemid
(o mesmo queGROUP BY ROLLUP((itemid),(proddte))
). Demo em SEDEGROUP BY ROLLUP
menos confuso, mas é bastante subjetivo. Também fico sempre nervoso quando leio coisas comoThe non-ISO compliant WITH ROLLUP, WITH CUBE, and ALL syntax is deprecated
- por que tenho tendência a favorecerGROUPING SETS
.Essa sintaxe também é válida:
É um pouco confuso quando a gente vê pela primeira vez, mas você só precisa se lembrar de que as funções da janela - por exemplo
sum() over ()
- são aplicadas após as funções,group by
então tudo o que pode aparecer na lista de seleção de um grupo por consulta pode ser colocado dentro de uma janela agregada. Então (oqty
não pode mas) osum(qty)
pode ser colocado dentrosum() over ()
:Dito isto, prefiro a
GROUPING SETS
consulta fornecida por Aaron Bertrand. A soma total precisa ser mostrada uma vez e não em todas as linhas.Observe também que, embora a soma das somas possa ser usada para calcular a soma total, se você quiser a contagem total, será necessário usar a soma das contagens (e não a contagem de contagens!):
E se alguém quisesse a média sobre toda a mesa, seria ainda mais complicado:
porque a média das médias não é a mesma que a média geral. (Se você tentar,
avg(avg(qty)) over ()
verá que pode resultar em um resultado diferente da média geral acima.)fonte
Uma maneira possível é envolver o primeiro
GROUP BY
no CTE :fonte