简体   繁体   中英

Postgres query for recursive operation on rows

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

I want to calculate the difference of each b for any a

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

OUTPUT:

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

Is it possible to recursively apply a function over all of the table rows?

You can use the LAG window function to get the diff between to rows:

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

You can then SUM that:

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)
select b - b0
from
    foo
    cross join
    (select b as b0 from foo where a = 1) s
;
 ?column? 
----------
        0
        1
      0.5
     -0.5

Due to the thousands of requests in the comments this is the elegant version:

select f1.b - f2.b
from
    foo f1
    cross join
    foo f2
where f2.a = 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM