Te traemos el hallazgo a esta impedimento, al menos eso creemos. Si continuas con alguna interrogante dínoslo y con gusto te responderemos
Solución:
Esta es una sintaxis válida, también:
sum(sum(qty)) over ()
Es un poco confuso cuando uno lo ve al principio, pero solo debe recordar que la ventana funciona, por ejemplo sum() over ()
– se aplican después de la group by
por lo que todo lo que puede aparecer en la lista de selección de un grupo por consulta se puede colocar dentro de un agregado de ventana. Entonces el qty
no puede sino) la sum(qty)
se puede colocar dentro sum() over ()
:
select sum(qty), itemid, proddte,
sum(sum(qty)) over () as grandtotal
from testtable
where ....
group by itemid, proddte ;
Habiendo dicho eso, preferiría el GROUPING SETS
consulta proporcionada por Aaron Bertrand. La suma total debe mostrarse una vez y no en todas las filas.
También tenga en cuenta que si bien la suma de las sumas se puede usar para calcular la suma total, si quisiera el recuento total, tendría que usar la suma de los recuentos (¡y no el recuento de los recuentos!):
sum(count(*)) over () as grand_count
Y si uno quisiera el promedio de toda la tabla, sería aún más complicado:
sum(sum(qty)) over ()
/ sum(count(qty)) over () as grand_average
porque la media de las medias no es lo mismo que la media de todos. (Si prueba el avg(avg(qty)) over ()
verá que puede arrojar un resultado diferente al gran promedio anterior).
CREATE TABLE #foo
(
itemid int,
proddte date,
qty int
);
INSERT #foo(itemid,proddte,qty) VALUES
(1,'20140101',5),(1,'20140102',7),(2,'20150101',10);
-- if it really needs to be a column with the same value
-- in every row, just calculate once and assign it to a variable
DECLARE @sum int = (SELECT SUM(qty) FROM #foo);
SELECT itemid, proddte, GroupedSum = SUM(qty), GrandTotal = @sum
FROM #foo
GROUP BY itemid, proddte;
-- if the grand total can be expressed on its own row,
-- you can use GROUP BY GROUPING SETS:
SELECT itemid, proddte, SUM(qty)
FROM #foo GROUP BY GROUPING SETS((),(itemid,proddte));
-- if that syntax is confusing, you can use a less
-- efficient UNION ALL:
SELECT itemid, proddte, SUM(qty)
FROM #foo GROUP BY itemid,proddte
UNION ALL
SELECT NULL, NULL, SUM(qty)
FROM #foo;
GO
DROP TABLE #foo;
los GROUP BY GROUPING SETS
es básicamente un UNION ALL
. los ()
significa simplemente tomar el SUM
independientemente de la agrupación, cualquier otro grupo enumerado se agrega por separado. Probar GROUP BY GROUPING SETS ((itemid),(itemid,proddte))
para ver la diferencia.
Para más detalles ver la documentación:
Uso de GROUP BY con ROLLUP, CUBE y GROUPING SETS
Como mencionó Andriy, la consulta anterior también podría escribirse usando:
GROUP BY ROLLUP( (itemid,proddte) )
Tenga en cuenta que las dos columnas están encerradas en un par de paréntesis adicionales, lo que las convierte en una sola unidad. Andriy escribió una demostración alojada en Stack Exchange Data Explorer.
Una posible forma de evitarlo es envolver la primera GROUP BY
en CET:
WITH
CTE
AS
(
select
itemid
,proddte
,sum(qty) AS SumQty
from testtable
where ....
group by itemid, proddte
)
SELECT
itemid
,proddte
,SumQty
,SUM(SumQty) OVER () AS grandtotal
FROM CTE
;
Sección de Reseñas y Valoraciones
No se te olvide difundir este tutorial si si solucionó tu problema.