SQL Server sum y distinct – Sumar una vez con registros repetidos

publicado por: Anonymous

Tengo esta tabla de gastos y necesito sumar la columna Total.

introducir la descripción de la imagen aquí

El problema es que la tabla tiene en cuenta los productos, y al realizar el sum me suma varias veces el total de una nota (porque en una misma nota había varios productos). Lo que quiero es sumar el total pero únicamente una vez por nota. ¿Cómo lo podría hacer?

Por ejemplo:
Esta es una muestra de la tabla. Como se observa, la nota 32097 aparece dos veces, ya que en una nota hay dos productos. La columna total que aparece es la columna Total por nota, por eso requiero un distinct a nota y luego un sum a total.

Es decir, necesito sumar únicamente una vez por nota.

La consulta que tengo hasta ahora

select sum(Total)
from Gastos                   
where FechaGasto>='2017-01-01'and FechaGasto<='2017-12-31' and 
NombrePartida like '%activo%' 

solución

OPCION 1: anidar la query en una subtabla con DISTINCT

Se supone que sólo tienes un precio por nota, y que por tanto, sólo se generará una repetición por nota.

select SUM(subtabla.Total) from 
(select DISTINCT nota, Total
where FechaGasto >='2017-01-01'and FechaGasto<='2017-12-31' and 
NombrePartida like '%activo%') as subtabla

OPCION 2: utilizar la función GROUP BY combinada con MAX o 1

Group by es una función que agrupará los resultados por el campo que
le sugieras. La potencia de estas funciones se aprovecha porque
además, los campos sumatorios como SUM, realizan la agregación
en base al campo del GROUP BY.

Si además tienes me cuenta que MAX te dará el valor máximo de una de las notas, únicamente te sacará una por línea, y no las dos ocurrencias.

select nota, MAX(Total) as Total into #agrupada
from Gastos                   
where FechaGasto>='2017-01-01'and FechaGasto<='2017-12-31' and 
NombrePartida like '%activo%' 
GROUP BY nota  

Aquí ya tendrás la tabla temporal #agrupada sólo con los max por nota, es decir una línea por nota.

Así que consultas la tabla temporal ahora, y verás el total

   select sum(Total) from #agrupada

Puedes hacer lo mismo también anidando la tabla en el from, como en la opción inicial.

Suponiendo que para cada nota siempre tendrás el mismo “Total”. también puedes hacer (en dos pasos, con tabla temporal)

select DISTINCT Nota, Total into #agrupada
from Gastos                   
where FechaGasto>='2017-01-01'and FechaGasto<='2017-12-31' and 
NombrePartida like '%activo%' 
GROUP BY nota 

select sum(Total) from #agrupada

OPCION QUE CALCULA EL IVA EN FUNCION DEL CAMPO IVA

Atendiendo al comentario, se genera la siguiente consulta tambien

select sum(Total)
from ( 
  SELECT distinct nota,
  CASE
   WHEN iva = 1 THEN totalxproducto * 1.16    
   WHEN iva = 0 THEN totalxproducto
  END as Total
  from Gastos                   
  where FechaGasto>='2017-01-01'and FechaGasto<='2017-12-31
  and NombrePartida like '%activo%' 
 )

Opción Más optimizada (no le hace falta eliminar duplicados)

  SELECT SUM(CASE
        WHEN iva = 1 THEN totalxproducto * 1.16   
        WHEN iva = 0 THEN totalxproducto
        END)
  from Gastos                   
  where FechaGasto>='2017-01-01'and FechaGasto<='2017-12-31
  and NombrePartida like '%activo%' 

Algunos links:

https://programacion.net/articulo/tablas_temporales_en_el_sql_server_281

https://docs.microsoft.com/es-es/previous-versions/sql/sql-server-2008-r2/ms190750(v=sql.105)

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *