'Calculate sum of partial table with SQL
I have the following table:
+-------+------------+
| level | count(uid) |
+-------+------------+
| 3 | 1 |
| 4 | 1 |
| 0 | 1 |
| 2 | 3 |
+-------+------------+
I want to return:
+-------+------------+
| level | ans |
+-------+------------+
| 3 | 2 |
| 4 | 1 |
| 0 | 6 |
| 2 | 5 |
+-------+------------+
I want to calculate: for each level, calculate select sum(count(uid)) where level >= level
For example, the first row, we sum all levels >= level 3, which yields 1 + 1 = 2. for the last row, we sum all levels >= level 2 which is 3 + 1 + 1 = 5
Solution 1:[1]
for each level, you can sum up the uid for all the levels that are higher than the current one you are checking.
SELECT a.leveled,
count_uid + (
select
if (sum(count_uid) is null, 0, sum(count_uid))
from levels b
WHERE a.leveled < b.leveled
ORDER BY a.leveled
) as ans
FROM levels a
Solution 2:[2]
I figured it out!
Suppose the table name is tmp
and count(uid)
as res
There are 2 solutions: The following example works for StarRocks OLAP db
Self inner join:
select
t1.level,
SUM(t2.res) as retention
from
tmp t1
inner join tmp t2 on t1.level <= t2.level
group by
t1.level;
Join is expensive, we can optimize it w/ a simple window function:
select
tmp.level,
SUM(tmp.res) OVER(
ORDER BY
tmp.level ROWS BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING
) AS retention
from
tmp
order by
tmp.level;
Result:
+-------+-----------+
| level | retention |
+-------+-----------+
| 0 | 6 |
| 2 | 5 |
| 3 | 2 |
| 4 | 1 |
+-------+-----------+
4 rows in set (0.02 sec)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jocohan |
Solution 2 | Stan Shen |