Home > OS >  Extract previous row calculated value for use in current row calculations - Postgres
Extract previous row calculated value for use in current row calculations - Postgres

Time:06-04

Have a requirement where I would need to rope the calculated value of the previous row for calculation in the current row.

The following is a sample of how the data currently looks :-

ID Date Days
1 2022-01-15 30
2 2022-02-18 30
3 2022-03-15 90
4 2022-05-15 30

The following is the output What I am expecting :-

ID Date Days CalVal
1 2022-01-15 30 2022-02-14
2 2022-02-18 30 2022-03-16
3 2022-03-15 90 2022-06-14
4 2022-05-15 30 2022-07-14

The value of CalVal for the first row is Date Days From the second row onwards it should take the CalVal value of the previous row and add it with the current row Days

Is there anyway we can achieve the above via Postgres SQL? I have been tinkering with window functions and even recursive CTEs but have had no luck :(

Would appreciate any direction!

Thanks in advance!

CodePudding user response:

select 
    id,
    date,
    coalesce(
        days - (lag(days, 1) over (order by date, days))
        , days) as days,
     first_date   cast(days as integer) as newdate
from
    (
        select 
            -- get a running sum of days
            id,
            first_date,
            date,
            sum(days) over (order by date, days) as days
        from
        (
            select 
                -- get the first date
                id,
                (select min(date) from table1) as first_date, 
                date,
                days
            from 
                table1
        ) A
    ) B

This query get the exact output you described. I'm not at all ready to say it is the best solution but the strategy employed is to essential create a running total of the "days" ... this means that we can just add this running total to the first date and that will always be the next date in the desired sequence. One finesse: to put the "days" back into the result, we calculated the current running total less the previous running total to arrive at the original amount.

CodePudding user response:

assuming that table name is table1

select 
  id, 
  date, 
  days, 
  first_value(date) over (order by id)   
   (sum(days) over (order by id rows between unbounded preceding and current row))
   *interval '1 day' calval
 from table1;

We just add cumulative sum of days to first date in table. It's not really what you want to do (we don't need date from previous row, just cumulative days sum)

  • Related