The latest version of SQL Server (2012) permits the following.
SELECT
RowID,
Col1,
SUM(Col1) OVER(ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
FROM tablehh
ORDER BY RowId
or
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
This is even faster. Partitioned version completes in 34 seconds over 5 million rows for me.
Thanks to Peso, who commented on the SQL Team thread referred to in another answer.
Answer from Gareth Adamson on Stack OverflowThe latest version of SQL Server (2012) permits the following.
SELECT
RowID,
Col1,
SUM(Col1) OVER(ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
FROM tablehh
ORDER BY RowId
or
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
This is even faster. Partitioned version completes in 34 seconds over 5 million rows for me.
Thanks to Peso, who commented on the SQL Team thread referred to in another answer.
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
SQL Fiddle example
Output
| ID | SOMENUMT | SUM |
-----------------------
| 1 | 10 | 10 |
| 2 | 12 | 22 |
| 3 | 3 | 25 |
| 4 | 15 | 40 |
| 5 | 23 | 63 |
Edit: this is a generalized solution that will work across most db platforms. When there is a better solution available for your specific platform (e.g., gareth's), use it!
Cumulative sum or running sum
cumulative calculation
sql - Create a Cumulative Sum Column in MySQL - Stack Overflow
Cumulative Sum with Conditions
Hello!
I am trying to write a SQL query using a combination of CTE and windows function to calculate a cumulative sum of the count of product.
My apologize as I'm using my mobile but here is an example of the dataset
Productcode RATE1 RATE1 RATE3 RATE1 RATE3 RATE2
The original table has a lot of columns but I'm only interested into 1. It also has customer id but a customer can only have 1 product. There is also date row but I'm not interested in the date
I wrote the below with the idea of taking a column out of many from the original dataset, group the product code and get individual count of each rate and finally add a column running a cumulative sum
WITH testtable AS (Select Productcode ,Count(*) as Freq From table group by 1) Select Productcode ,Sum(Freq) over (partition by productcode) as cumul From testtable
The output is essentially a duplicate of the column Freq as opposed to the cumulative Freq as I hoped.
I also appreciate that there is certainly an easier way of getting this done but I still would like to know why it is not working?
Thanks for your inputs!
Edit: moved 'AS' to the correct position Edit 2: sample dataset and further clarifications Edit 3: solved SUM(COLUMN) OVER (ORDER BY productid)
Using a correlated query:
SELECT t.id,
t.count,
(SELECT SUM(x.count)
FROM TABLE x
WHERE x.id <= t.id) AS cumulative_sum
FROM TABLE t
ORDER BY t.id
Using MySQL variables:
SELECT t.id,
t.count,
@running_total := @running_total + t.count AS cumulative_sum
FROM TABLE t
JOIN (SELECT @running_total := 0) r
ORDER BY t.id
Note:
- The
JOIN (SELECT @running_total := 0) ris a cross join, and allows for variable declaration without requiring a separateSETcommand. - The table alias,
r, is required by MySQL for any subquery/derived table/inline view
Caveats:
- MySQL specific; not portable to other databases
- The
ORDER BYis important; it ensures the order matches the OP and can have larger implications for more complicated variable usage (IE: psuedo ROW_NUMBER/RANK functionality, which MySQL lacks)
If performance is an issue, you could use a MySQL variable:
set @csum := 0;
update YourTable
set cumulative_sum = (@csum := @csum + count)
order by id;
Alternatively, you could remove the cumulative_sum column and calculate it on each query:
set @csum := 0;
select id, count, (@csum := @csum + count) as cumulative_sum
from YourTable
order by id;
This calculates the running sum in a running way :)