我正在努力在PgSQL上编写查询。
我的表有值,我必须累加它的值,但是结果必须是有界的(在这种情况下,值为0到30之间)。
这是数据集和预期结果:
+----+--------+------------------------------------+
| id | value | expected_cumulated_sum_with_limits |
+----+--------+------------------------------------+
| 1 | 3 | 3 |
| 2 | 4 | 7 |
| 3 | -2 | 5 |
| 4 | -28 | 0 |
| 5 | 45 | 30 |
| 6 | -3 | 27 |
+----+--------+------------------------------------+
我用WINDOW尝试了一些查询(但是我只能做一个总和,没有0,30的限制)和一些递归CTE(但是我不确定这是个好方法)。
感谢您的帮助
答案 0 :(得分:2)
我对递归CTE不太满意,因此可能有更好的方法,但这可行:
CREATE TABLE cum_bounded (id int4, value int4);
INSERT INTO cum_bounded VALUES (1,3), (2,4), (3,-2), (4,-28), (5,45), (6,-3);
如果ID没有空格,并且您要计算按ID排序的值:
WITH RECURSIVE cum AS (
(SELECT c.id, c.value, c.value AS cum_value FROM cum_bounded AS c ORDER BY c.id LIMIT 1)
UNION ALL
SELECT c.id, c.value,
CASE WHEN cum.cum_value + c.value < 0 THEN 0
WHEN cum.cum_value + c.value > 30 THEN 30
ELSE cum.cum_value + c.value END
FROM cum_bounded AS c
JOIN cum ON cum.id = c.id - 1
)
SELECT * FROM cum;
如果ID有空白,则检查下一个ID是什么(按ID排序)。也可以改为计算row_number()
:
WITH RECURSIVE cum AS (
WITH cb AS (SELECT id, lead(id) OVER(ORDER BY c.id) AS next_id, c.value FROM cum_bounded AS c)
(SELECT c.id, c.next_id, c.value, c.value AS cum_value FROM cb AS c ORDER BY 2 LIMIT 1)
UNION ALL
SELECT c.id, c.next_id, c.value,
CASE WHEN cum.cum_value + c.value < 0 THEN 0
WHEN cum.cum_value + c.value > 30 THEN 30
ELSE cum.cum_value + c.value END
FROM cb AS c
JOIN cum ON cum.next_id = c.id
)
SELECT id, value, cum_value FROM cum;