I have a table that looks like this:
id count
1 100
2 50
3 10
I want to add a new column called cumulative_sum, so the table wou
MySQL 8.0/MariaDB supports windowed SUM(col) OVER():
SELECT *, SUM(cnt) OVER(ORDER BY id) AS cumulative_sum
FROM tab;
Output:
┌─────┬──────┬────────────────┐
│ id │ cnt │ cumulative_sum │
├─────┼──────┼────────────────┤
│ 1 │ 100 │ 100 │
│ 2 │ 50 │ 150 │
│ 3 │ 10 │ 160 │
└─────┴──────┴────────────────┘
db<>fiddle
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
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:
JOIN (SELECT @running_total := 0) r
is a cross join, and allows for variable declaration without requiring a separate SET
command. r
, is required by MySQL for any subquery/derived table/inline view Caveats:
ORDER BY
is 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)You could also create a trigger that will calculate the sum before each insert
delimiter |
CREATE TRIGGER calCumluativeSum BEFORE INSERT ON someTable
FOR EACH ROW BEGIN
SET cumulative_sum = (
SELECT SUM(x.count)
FROM someTable x
WHERE x.id <= NEW.id
)
set NEW.cumulative_sum = cumulative_sum;
END;
|
I have not tested this