Cómo obtener la suma acumulada
declare @t table
(
id int,
SomeNumt int
)
insert into @t
select 1,10
union
select 2,12
union
select 3,3
union
select 4,15
union
select 5,23
select * from @t
la selección anterior me devuelve lo siguiente.
id SomeNumt
1 10
2 12
3 3
4 15
5 23
¿Cómo obtengo lo siguiente?
id srome CumSrome
1 10 10
2 12 22
3 3 25
4 15 40
5 23 63
select t1.id, t1.SomeNumt, SUM(t2.SomeNumt) as sum
from @t t1
inner join @t t2 on t1.id >= t2.id
group by t1.id, t1.SomeNumt
order by t1.id
Ejemplo de violín SQL
Producción
| ID | SOMENUMT | SUM |
-----------------------
| 1 | 10 | 10 |
| 2 | 12 | 22 |
| 3 | 3 | 25 |
| 4 | 15 | 40 |
| 5 | 23 | 63 |
Editar: esta es una solución generalizada que funcionará en la mayoría de las plataformas de base de datos. Cuando haya una mejor solución disponible para su plataforma específica (por ejemplo, la de Gareth), ¡úsela!
La última versión de SQL Server (2012) permite lo siguiente.
SELECT
RowID,
Col1,
SUM(Col1) OVER(ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
FROM tablehh
ORDER BY RowId
o
SELECT
GroupID,
RowID,
Col1,
SUM(Col1) OVER(PARTITION BY GroupID ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
FROM tablehh
ORDER BY RowId
Esto es aún más rápido. La versión particionada se completa en 34 segundos en más de 5 millones de filas.
Gracias a Peso, quien comentó sobre el hilo del Equipo SQL al que se hace referencia en otra respuesta.
Para SQL Server 2012 en adelante podría ser fácil:
SELECT id, SomeNumt, sum(SomeNumt) OVER (ORDER BY id) as CumSrome FROM @t
Porque ORDER BY
la cláusula de SUM
forma predeterminada significa RANGE UNBOUNDED PRECEDING AND CURRENT ROW
marco de ventana ("Observaciones generales" en https://msdn.microsoft.com/en-us/library/ms189461.aspx )
Primero creemos una tabla con datos ficticios:
Create Table CUMULATIVESUM (id tinyint , SomeValue tinyint)
Ahora insertemos algunos datos en la tabla;
Insert Into CUMULATIVESUM
Select 1, 10 union
Select 2, 2 union
Select 3, 6 union
Select 4, 10
Aquí me estoy uniendo a la misma mesa (autounión)
Select c1.ID, c1.SomeValue, c2.SomeValue
From CumulativeSum c1, CumulativeSum c2
Where c1.id >= c2.ID
Order By c1.id Asc
Resultado:
ID SomeValue SomeValue
-------------------------
1 10 10
2 2 10
2 2 2
3 6 10
3 6 2
3 6 6
4 10 10
4 10 2
4 10 6
4 10 10
Aquí vamos, ahora simplemente sumamos el valor de t2 y obtendremos la respuesta:
Select c1.ID, c1.SomeValue, Sum(c2.SomeValue) CumulativeSumValue
From CumulativeSum c1, CumulativeSum c2
Where c1.id >= c2.ID
Group By c1.ID, c1.SomeValue
Order By c1.id Asc
Para SQL Server 2012 y superior (rendimiento mucho mejor):
Select
c1.ID, c1.SomeValue,
Sum (SomeValue) Over (Order By c1.ID )
From CumulativeSum c1
Order By c1.id Asc
Resultado deseado:
ID SomeValue CumlativeSumValue
---------------------------------
1 10 10
2 2 12
3 6 18
4 10 28
Drop Table CumulativeSum