SQL GROUP BY CASE instrucción con función agregada
-
05-07-2019 - |
Pregunta
Tengo una columna que se parece a esto:
CASE
WHEN col1 > col2 THEN SUM(col3*col4)
ELSE 0
END AS some_product
Y me gustaría ponerlo en mi cláusula GROUP BY, pero esto parece causar problemas porque hay una función agregada en la columna. ¿Hay alguna forma de agrupar por un alias de columna como some_product
en este caso, o tengo que poner esto en una subconsulta y agrupar en eso?
Solución
Mi opinión es que realmente no quieres GROUP BY
some_product.
La respuesta a: " ¿Hay una manera de GROUP BY
un alias de columna como some_product en este caso, o debo poner esto en una subconsulta? y agrupar en eso? " es: no puede GRUPO POR
un alias de columna.
La cláusula SELECT
, donde se asignan los alias de columna, no se procesa hasta después de la cláusula GROUP BY
. Se podría utilizar una vista en línea o una expresión de tabla común (CTE) para que los resultados estén disponibles para la agrupación.
Vista en línea:
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 ...
Otros consejos
Si bien la la respuesta de Shannon es técnicamente correcta, parece una exageración.
La solución simple es que necesita colocar su resumen fuera de la declaración de case
.
Esto debería hacer el truco:
sum(CASE WHEN col1 > col2 THEN col3*col4 ELSE 0 END) AS some_product
Básicamente, su código anterior le dice a SQL que ejecute sum (X * Y)
para cada línea individualmente (dejando cada línea con su propia respuesta que no se puede agrupar).
La línea de código que he escrito toma la suma del producto, que es lo que quieres.
Si está agrupando por algún otro valor, entonces en lugar de lo que tiene,
escribelo como
Sum(CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END) as SumSomeProduct
Si, otoh, desea agrupar por
la expresión interna, (col3 * col4)
entonces
escriba el grupo por
para que coincida con la expresión sin / 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
Por último, si desea agrupar por el 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