J'ai ce code qui résume la quantité d'un certain article ( itemid
) et par son code de date de produit ( proddte
).
select sum(qty), itemid, proddte
from testtable where ....
group by itemid, proddte
Ce que je veux faire, c'est obtenir le total de tous qty
indépendamment de itemid/proddte
. J'ai essayé:
select sum(qty), itemid, proddte, sum(qty) over() as grandtotal
from testtable
where ....
group by itemid, proddte
Mais cela dit que j'aurais dû également le faire qty
dans l' group by
article. Si je l'ai fait, le résultat ne sera pas égal à mon résultat attendu.
Il n'est pas absolument nécessaire de la représenter comme une colonne distincte, avec la même valeur dans chaque ligne. Toute représentation est acceptée tant que je peux afficher le total global.
la source
GROUP BY ROLLUP((itemid,proddte))
produirait le même résultat et pourrait être moins déroutant.itemid
Ie Il est équivalent àGROUP BY GROUPING SETS((),(itemid),(itemid,proddte))
GROUP BY ROLLUP(itemid,proddte)
, d'autre part, produirait en effet des sous-totaux (supplémentaires) suritemid
(les mêmes queGROUP BY ROLLUP((itemid),(proddte))
). Démo chez SEDEGROUP BY ROLLUP
moins déroutant, mais c'est plutôt subjectif. Je suis aussi toujours nerveux quand je lis des choses commeThe non-ISO compliant WITH ROLLUP, WITH CUBE, and ALL syntax is deprecated
- pourquoi j'ai tendance à favoriserGROUPING SETS
.C'est aussi une syntaxe valide:
C'est un peu déroutant quand on le voit au début, mais il suffit de se rappeler que les fonctions de fenêtre - par exemple
sum() over ()
- sont appliquées après legroup by
afin que tout ce qui peut apparaître dans la liste de sélection d'un groupe par requête puisse être placé dans un agrégat de fenêtre. Donc (leqty
ne peut pas mais) lesum(qty)
peut être placé à l'intérieursum() over ()
:Cela dit, je préfère la
GROUPING SETS
requête fournie par Aaron Bertrand. La somme totale doit être affichée une fois et non sur chaque ligne.Notez également que si la somme des sommes peut être utilisée pour calculer la somme totale, si vous voulez le nombre total, vous devrez utiliser la somme des comptes (et non le nombre de comptes!):
Et si l'on voulait la moyenne sur toute la table, ce serait encore plus compliqué:
parce que la moyenne des moyennes n'est pas la même que la moyenne dans l'ensemble. (Si vous essayez,
avg(avg(qty)) over ()
vous verrez que cela peut donner un résultat différent de la grande moyenne ci-dessus.)la source
Une solution possible consiste à envelopper le premier
GROUP BY
dans CTE :la source