webentwicklung-frage-antwort-db.com.de

SQL GROUP BY CASE-Anweisung mit Aggregatfunktion

Ich habe eine Spalte, die ungefähr so ​​aussieht:

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

Und ich würde es gerne in meine GROUP BY-Klausel aufnehmen, aber dies scheint Probleme zu verursachen, da die Spalte eine Aggregatfunktion enthält. Gibt es eine Möglichkeit zum Gruppieren nach einem Spaltenalias wie some_product in diesem Fall oder muss ich dies in eine Unterabfrage und eine Gruppe darauf setzen?

40
Bryan Ward

Meine Vermutung ist, dass Sie nicht wirklich wollen, GROUP BY irgendein_ Produkt.

Das Antwort auf: "Gibt es einen Weg zu GROUP BY in diesem Fall ein Spaltenalias wie some_product, oder muss ich dies in eine Unterabfrage einfügen und darauf gruppieren? "is: Sie können GROUP BY ein Spaltenalias.

Die SELECT -Klausel, in der Spaltenaliasnamen zugewiesen werden, wird erst nach dem GROUP BY Klausel. Eine Inline-Ansicht oder ein allgemeiner Tabellenausdruck (Common Table Expression, CTE) können verwendet werden, um die Ergebnisse für die Gruppierung verfügbar zu machen.

Inline-Ansicht:

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

Obwohl Shannons Antwort technisch korrekt ist, sieht es nach Overkill aus.

Die einfache Lösung besteht darin, dass Sie Ihre Summe außerhalb der case -Anweisung einfügen müssen. Dies sollte den Trick machen:

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

Grundsätzlich weist Ihr alter Code SQL an, die Funktion sum(X*Y) für jede Zeile einzeln auszuführen (wobei jede Zeile ihre eigene Antwort hat, die nicht gruppiert werden kann).

Die Codezeile, die ich geschrieben habe, nimmt das Summenprodukt, was Sie wollen.

34
user2076246

Wenn Sie nach einem anderen Wert gruppieren, haben Sie anstelle dessen, was Sie haben,

schreibe es als

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

Wenn Sie aber group By der interne Ausdruck, (col3*col4) dann

schreiben Sie die group By passend zum Ausdruck ohne 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 

Schließlich, wenn Sie nach dem tatsächlichen Aggregat gruppieren möchten

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
2
Charles Bretana