Postgres 查询对行的递归操作


create table foo (a int, b float);
insert into foo values (1, 2), (2,3),(3,2.5),(4,1.5);
 a |  b  
---+-----
 1 |   2
 2 |   3
 3 | 2.5
 4 | 1.5

我想计算任何b的差值a

select RECURSIVE diff (?,?) on b where a=1

输出:

 a |  diff  
---+-----
 1 |   0
 2 |   1
 3 | .5
 4 | -.5

是否可以在所有表行上递归应用函数?

select b - b0
from
    foo
    cross join
    (select b as b0 from foo where a = 1) s
;
 ?column? 
----------
        0
        1
      0.5
     -0.5

由于评论中有成千上万的请求,这是优雅的版本:

select f1.b - f2.b
from
    foo f1
    cross join
    foo f2
where f2.a = 1
您可以使用

LAG 窗口函数来获取行之间的差异:

SELECT b - LAG(b) OVER (ORDER BY a ASC) 
FROM foo;
┌──────────┐
│ ?column? │
├──────────┤
│   (null) │
│        1 │
│     -0.5 │
│       -1 │
└──────────┘
(4 rows)

然后,您可以SUM

SELECT SUM(d) OVER (ORDER BY a ASC)
FROM (
    SELECT a, b - LAG(b) OVER (ORDER BY a ASC)
    FROM foo
) sub(a, d);
┌────────┐
│  sum   │
├────────┤
│ (null) │
│      1 │
│    0.5 │
│   -0.5 │
└────────┘
(4 rows)