PgSQL上的累积值和有界值之和
我正在努力编写关于PgSQL的查询 我的表有值,我必须累加它的值,但结果必须有界(在这种情况下介于0和30之间) 以下是数据集和预期结果:PgSQL上的累积值和有界值之和,sql,database,postgresql,recursion,sum,Sql,Database,Postgresql,Recursion,Sum,我正在努力编写关于PgSQL的查询 我的表有值,我必须累加它的值,但结果必须有界(在这种情况下介于0和30之间) 以下是数据集和预期结果: +----+--------+------------------------------------+ | id | value | expected_cumulated_sum_with_limits | +----+--------+------------------------------------+ | 1 | 3 |
+----+--------+------------------------------------+
| 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(但我不确定这是一个好方法)
感谢您的帮助我对递归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;
演示:您所说的必须在0和30之间有界是什么意思?如果该值非常大,并且会导致累计总和低于0或高于30,该怎么办?对于第
行id=5
,为什么具有限制的预期累计总和的值为30而不是22?@OtoShavadze前一行的调整累计值为0,因此,45被添加到0中,而不是实际的累积量。我认为最简单的方法是使用游标。非常好,递归确实是一种很好的方法,谢谢@ukasz kamiński!
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;