Home > Net >  postgres - window function - date difference within a groups
postgres - window function - date difference within a groups

Time:11-23

I searched and saw potential results but with my skills I'm not able to adapt them.

I have a table:

date record status
1.10.2022 open
2.10.2022 waiting
3.10.2022 approved
5.10.2022 open
6.10.2022 waiting
8.10.2022 approved
10.10.2022 open
12.10.2022 waiting

and need the date difference between 'open' and 'approved' within groups starting with 'open' and ending with 'approved'. The last group is not yet approved. There the date difference is between the last open and today (=15.10.2022 just as example)

date record status group/rank date diff
1.10.2022 open 1 2
2.10.2022 waiting 1 2
3.10.2022 approved 1 2
5.10.2022 open 2 3
6.10.2022 waiting 2 3
8.10.2022 approved 2 3
10.10.2022 open 3 5
12.10.2022 waiting 3 5

Questions then:

  1. How do I define the groups. I thought maybe with a rank because the orig table has thousands of rows
  2. How does the date diff function look like that considers only open and approved plus the special case where the record is not yet approved
  3. How to apply this date diff to the groups only

Thanks a lot :-)

CodePudding user response:

Your idea was good; a CTE to manage the case where you need to use the current day was all you were missing (See EXISTS).

WITH RankedStatus AS (
    SELECT MyTable.*,
           DENSE_RANK() OVER (PARTITION BY RecordStatus ORDER BY Date) AS Rank
    FROM MyTable
)
SELECT RS.*,
       CASE WHEN EXISTS(SELECT FROM RankedStatus WHERE Rank = RS.Rank and RecordStatus = 'approved')
       THEN MAX(Date) OVER (PARTITION BY Rank)
       ELSE CURRENT_DATE END
       - MIN(Date) OVER (PARTITION BY Rank) AS DateDiff
FROM RankedStatus RS

CodePudding user response:

Thanks a lot for the response. To make it a bit more complicated. How can I then partition as displayed in the Group column added for illustration?

In words but don't know to convert to code: status 'approved' always defines the end. Only an 'open' after 'approval' defines the start. The other 'open' are not relevant. The date diff is then between start and end of each group.

date status Group mindate maxdate Datediff in group (days)
1.10.2022 open Group 1 Starts 1.10.2022 5.10.2022 4
2.10.2022 waiting 1.10.2022 5.10.2022 4
3.10.2022 open 1.10.2022 5.10.2022 4
4.10.2022 waiting 1.10.2022 5.10.2022 4
5.10.2022 approved Group 1 Ends 1.10.2022 5.10.2022 4
7.10.2022 open Group 2 Start 7.10.2022 15.10.2022 8
8.10.2022 waiting 7.10.2022 15.10.2022 8
9.10.2022 open 7.10.2022 15.10.2022 8
10.10.2022 waiting 7.10.2022 15.10.2022 8
11.10.2022 open 7.10.2022 15.10.2022 8
12.10.2022 waiting 7.10.2022 15.10.2022 8
15.10.2022 approved Group 2 Ends 7.10.2022 15.10.2022 8
17.10.2022 open Group 3 Starts 17.10.2022 20.10.2022 8
20.10.2022 waiting
  • Related