PostgreSQL - 如何获取先前(滞后)的计算值
PostgreSQL - How to get the previous(lag) calculated value
我想获取之前(滞后)的计算值?
id | value
-------|-------
1 | 1
2 | 3
3 | 5
4 | 7
5 | 9
我想要实现的是:
id | value | new value
-------|-------|-----------
1 | 1 | 10 <-- 1 * lag(new_value)
2 | 3 | 30 <-- 3 * lag(new_value)
3 | 5 | 150 <-- 5 * lag(new_value)
4 | 7 | 1050 <-- 7 * lag(new_value)
5 | 9 | 9450 <-- 9 * lag(new_value)
我尝试过的:
SELECT value,
COALESCE(lag(new_value) OVER () * value, 10) AS new_value
FROM table
错误:
ERROR: column "new_value" does not exist
糟糕,这并不像我想的那么容易。得到了非常接近的结果,但仍需要一些调整。
WITH RECURSIVE t(n, v) AS (
SELECT MIN(value), 10
FROM Table1
UNION ALL
SELECT (SELECT min(value) from Table1 WHERE value > n),
(SELECT min(value) from Table1 WHERE value > n) * v
FROM t
JOIN Table1 on t.n = Table1.value
)
SELECT n, v
FROM t;
与 Juan 的回答类似,但我想我还是 post 了。它至少避免了对 ID 列的需要,并且末尾没有空行:
with recursive all_data as (
select value, value * 10 as new_value
from data
where value = 1
union all
select c.value,
c.value * p.new_value
from data c
join all_data p on p.value < c.value
where c.value = (select min(d.value)
from data d
where d.value > p.value)
)
select *
from all_data
order by value;
想法是将递归部分中的一行正好连接到 "parent" 行。虽然 "exactly one parent" 可以通过派生的 table 和横向连接来完成(令人惊讶的是 确实 允许 limit
)。不幸的是,递归部分中来自 "child" 的 "exactly one row" 只能使用带有 min()
的子 select 来完成。
如果在递归部分也可以使用 order by
和 limit
,那么 where c.value= (...)
就没有必要了,但不幸的是,当前不支持Postgres 版本。
我想获取之前(滞后)的计算值?
id | value
-------|-------
1 | 1
2 | 3
3 | 5
4 | 7
5 | 9
我想要实现的是:
id | value | new value
-------|-------|-----------
1 | 1 | 10 <-- 1 * lag(new_value)
2 | 3 | 30 <-- 3 * lag(new_value)
3 | 5 | 150 <-- 5 * lag(new_value)
4 | 7 | 1050 <-- 7 * lag(new_value)
5 | 9 | 9450 <-- 9 * lag(new_value)
我尝试过的:
SELECT value,
COALESCE(lag(new_value) OVER () * value, 10) AS new_value
FROM table
错误:
ERROR: column "new_value" does not exist
糟糕,这并不像我想的那么容易。得到了非常接近的结果,但仍需要一些调整。
WITH RECURSIVE t(n, v) AS (
SELECT MIN(value), 10
FROM Table1
UNION ALL
SELECT (SELECT min(value) from Table1 WHERE value > n),
(SELECT min(value) from Table1 WHERE value > n) * v
FROM t
JOIN Table1 on t.n = Table1.value
)
SELECT n, v
FROM t;
与 Juan 的回答类似,但我想我还是 post 了。它至少避免了对 ID 列的需要,并且末尾没有空行:
with recursive all_data as (
select value, value * 10 as new_value
from data
where value = 1
union all
select c.value,
c.value * p.new_value
from data c
join all_data p on p.value < c.value
where c.value = (select min(d.value)
from data d
where d.value > p.value)
)
select *
from all_data
order by value;
想法是将递归部分中的一行正好连接到 "parent" 行。虽然 "exactly one parent" 可以通过派生的 table 和横向连接来完成(令人惊讶的是 确实 允许 limit
)。不幸的是,递归部分中来自 "child" 的 "exactly one row" 只能使用带有 min()
的子 select 来完成。
如果在递归部分也可以使用 order by
和 limit
,那么 where c.value= (...)
就没有必要了,但不幸的是,当前不支持Postgres 版本。