Hacer un sum() dentro de otro sum()


16 de Noviembre del 2021

Buenas!!

Tengo la siguiente consulta donde calculo venta total por productos pero a su vez pertenecen a un grupo de productos, asi que quisiera ver como puedo agrupar esos resultados por grupo y hacer el sum() correspondiente para sacar las ventas por grupo.
Ya que no se puede hacer un sum() dentro de otro(), esa es la duda que tengo, como podria resolverlo?

select
g.idgrupo, case when c.descuento = 100 then 0 * sum(ch.cantidad) else ch.precio * sum(ch.cantidad) end as
venta
from
cheques c inner JOIN cheqdet ch ON c.folio = ch.foliodet
left join productos p on ch.idproducto = p.idproducto
left join grupos g on p.idgrupo = g.idgrupo
WHERE
c.cancelado = 0 and c.idempresa='0000000001' AND idturno = 740
group by
g.idgrupo, c.descuento, ch.precio
order by
g.idgrupo

el case es necesario ya que si la cuenta tiene descuento afecta a venta


Ivan
12 de Agosto del 2026

Hola,

El problema es que tu GROUP BY incluye ch.precio (y c.descuento), y eso es demasiado granular: como precio puede variar de una línea de detalle a otra dentro del mismo grupo, en la práctica estás creando un grupo distinto por cada combinación de idgrupo+precio+descuento, no un único grupo por idgrupo como quieres. Por eso te sale un sum() por cada línea en vez de un único total por grupo.

La solución es calcular el importe de cada línea individual primero (ahí sí usando el CASE con el descuento), y luego sumar esos importes ya calculados agrupando únicamente por idgrupo, en una subconsulta:

SELECT idgrupo, SUM(venta_linea) AS venta
FROM (
    SELECT
        g.idgrupo,
        CASE WHEN c.descuento = 100 THEN 0 ELSE ch.precio * ch.cantidad END AS venta_linea
    FROM cheques c
    INNER JOIN cheqdet ch ON c.folio = ch.foliodet
    LEFT JOIN productos p ON ch.idproducto = p.idproducto
    LEFT JOIN grupos g ON p.idgrupo = g.idgrupo
    WHERE c.cancelado = 0 AND c.idempresa = '0000000001' AND idturno = 740
) t
GROUP BY idgrupo
ORDER BY idgrupo;

La subconsulta interior calcula «cuánto vale esta línea concreta» (aplicando ya el descuento si toca), y la consulta exterior suma esas ventas por línea agrupando únicamente por idgrupo. No hay ningún sum() anidado dentro de otro sum(), que efectivamente no está permitido, pero separando en dos pasos (línea a línea primero, grupo después) consigues exactamente lo que buscas.

Ivan