SQL GROUP BY CASE-instructie met aggregatiefunctie

Ik heb een kolom die er ongeveer zo uitziet:

CASE
    WHEN col1 > col2 THEN SUM(col3*col4)
    ELSE 0
END AS some_product

En ik zou het in mijn GROUP BY-clausule willen plaatsen, maar dit lijkt problemen te veroorzaken omdat er een aggregatiefunctie in de kolom is. Is er een manier om in dit geval een kolomalias zoals some_productte GROUPEREN, of moet ik dit in een subquery en daarop groeperen?


Antwoord 1, autoriteit 100%

Mijn gok is dat je niet echt wilt GROUP BYeen_product.

Het antwoord op:“Is er een manier om in dit geval GROUP BYeen kolomalias zoals some_product te gebruiken, of moet ik dit in een subquery plaatsen en groep daarover?” is:u kunt een kolomalias niet GROUP BY.

De SELECT-clausule, waar kolomaliassen worden toegewezen, wordt pas verwerkt na de GROUP BY-clausule. Een inline view of Common Table Expression (CTE) kan worden gebruikt om de resultaten beschikbaar te maken voor groepering.

Inline-weergave:

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 ... 

Antwoord 2, autoriteit 72%

Hoewel Shannons antwoordtechnisch correct is, lijkt het overdreven.

De eenvoudige oplossing is dat u uw sommatie buiten de case-instructie moet plaatsen.
Dit zou moeten werken:

sum(CASE WHEN col1 > col2 THEN col3*col4 ELSE 0 END) AS some_product

Kortom, uw oude code vertelt SQL om de sum(X*Y)voor elke regel afzonderlijk uit te voeren (waardoor elke regel zijn eigen antwoord heeft dat niet kan worden gegroepeerd).

De coderegel die ik heb geschreven, neemt het somproduct, dat is wat je wilt.


Antwoord 3, autoriteit 10%

Als je groepeert op een andere waarde, dan in plaats van wat je hebt,

schrijf het als

Sum(CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END) as SumSomeProduct

Als, otoh, je de interne uitdrukking group By, (col3*col4)dan

schrijf de group Byzodat deze overeenkomt met de uitdrukking zonder de 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 

Ten slotte, als u wilt groeperen op basis van het werkelijke aggregaat

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

Antwoord 4, autoriteit 10%

Ik denk dat het antwoord vrij eenvoudig is (tenzij ik iets over het hoofd zie?)

SELECT    
CASE
    WHEN col1 > col2 THEN SUM(col3*col4)
    ELSE 0
END AS some_product
FROM some_table
GROUP BY
CASE
    WHEN col1 > col2 THEN SUM(col3*col4)
    ELSE 0
END

U kunt de CASE STATEMENT in de GROUP BY woordelijk plaatsen (minus de alias kolomnaam)

Other episodes