Instruction SQL GROUP BY CASE avec fonction d'agrégation
-
05-07-2019 - |
Question
J'ai une colonne qui ressemble à ceci:
CASE
WHEN col1 > col2 THEN SUM(col3*col4)
ELSE 0
END AS some_product
Et je voudrais le mettre dans ma clause GROUP BY, mais cela semble poser problème car il y a une fonction d'agrégat dans la colonne. Existe-t-il un moyen de GROUPER un alias de colonne tel que some_product
dans ce cas, ou dois-je mettre cela dans une sous-requête et un groupe?
La solution
Je suppose que vous ne voulez pas vraiment GROUP BY
un certain produit.
La réponse à: "Existe-t-il un moyen de GROUP BY
un alias de colonne tel que some_product dans ce cas, ou dois-je l'insérer dans une sous-requête et un groupe à ce sujet? " est: vous ne pouvez pas GROUP BY
un alias de colonne.
La clause SELECT
, dans laquelle les alias de colonne sont attribués, n'est traitée qu'après la clause GROUP BY
. Une vue en ligne ou une expression de table commune (CTE) peut être utilisée pour rendre les résultats disponibles pour le regroupement.
Vue en ligne:
select ...
from (select ... , CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END AS some_product
from ...
group by col1, col2 ... ) T
group by some_product ...
CTE:
with T as (select ... , CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END AS some_product
from ...
group by col1, col2 ... )
select ...
from T
group by some_product ...
Autres conseils
Bien que la réponse de Shannon soit techniquement correcte, elle ressemble à une overkill.
La solution simple consiste à placer votre sommation en dehors de l'instruction case
.
Cela devrait faire l'affaire:
sum(CASE WHEN col1 > col2 THEN col3*col4 ELSE 0 END) AS some_product
En gros, votre ancien code indique à SQL d’exécuter la somme (X * Y)
de chaque ligne individuellement (en laissant à chaque ligne sa propre réponse qui ne peut pas être groupée).
La ligne de code que j'ai écrite prend le produit somme, c'est ce que vous voulez.
Si vous groupez par une autre valeur, alors, au lieu de ce que vous avez,
écrivez-le comme
Sum(CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END) as SumSomeProduct
Si, otoh, vous souhaitez grouper par
l'expression interne, (col3 * col4)
, puis
écrivez le groupe By
pour qu'il corresponde à l'expression sans le SUM
...
Select Sum(Case When col1 > col2 Then col3*col4 Else 0 End) as SumSomeProduct
From ...
Group By Case When col1 > col2 Then col3*col4 Else 0 End
Enfin, si vous souhaitez grouper par agrégat réel
Select SumSomeProduct, Count(*), <other aggregate functions>
From (Select <other columns you are grouping By>,
Sum(Case When col1 > col2
Then col3*col4 Else 0 End) as SumSomeProduct
From Table
Group By <Other Columns> ) As Z
Group by SumSomeProduct