SQL GROUP BY CASE statement with aggregate function

Tenho uma coluna parecida com esta:
CASE
    WHEN col1 > col2 THEN SUM(col3*col4)
    ELSE 0
END AS some_product

e eu gostaria de colocá-lo no meu grupo por cláusula, mas isso parece causar problemas porque há uma função agregada na coluna. Existe uma maneira de agrupar por uma coluna alias como some_product Neste caso, ou eu preciso colocar isso em um subquery e grupo sobre isso?

Author: Bryan Ward, 2009-07-30

3 answers

O meu palpite é que não queres produzir.

A resposta: "existe uma maneira de GROUP BY um alias de coluna, tais como some_product neste caso, ou eu preciso colocar isso em uma subconsulta e um grupo em que?" is: You can not GROUP BY a column alias.

A Cláusula SELECT, em que os pseudónimos da coluna são atribuídos, só é processada após a cláusula GROUP BY. Uma visualização em linha ou expressão de tabela comum (CTE) pode ser usada para fazer os resultados disponível para agrupamento.

Vista em Linha:

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 ... 
 45
Author: Shannon Severance, 2013-01-16 18:15:34

Embora a resposta da Shannon esteja tecnicamente correcta, parece um exagero.

A solução simples é que você precisa colocar a sua soma fora da declaração case. Isto deve servir.

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

Basicamente, o seu código antigo diz ao SQL para executar o {[[2]} para cada linha individualmente (deixando cada linha com a sua própria resposta que não pode ser agrupada).

A linha de código que escrevi leva a soma do produto, que é o que você quer.

 29
Author: user2076246, 2017-05-23 12:02:39

Se você está agrupando por algum outro valor, então em vez do que você tem,

Escreva como

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

Se, otoh, quiser {[3] } a expressão interna, (col3*col4) Então

Escreva o group By para corresponder à expressão w / o o 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 

Finalmente, se quiser agrupar-se pelo agregado real

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
Author: Charles Bretana, 2012-07-19 14:23:13