Postgresql – How to merge overlapping time intervals if the interval not more than 4 minutes in PostgreSql

postgresql

How to merge overlapping time intervals if the interval not more than 4 minutes (for example only where id = 1).

I have the next table:

--------------------------------------
id | action    | date
--------------------------------------
1  | started   | 2020-08-18 13:51:02
1  | suspended | 2020-08-18 13:51:04
2  | started   | 2020-08-18 13:52:14
2  | suspended | 2020-08-18 13:52:17
3  | started   | 2020-08-18 13:52:21
3  | suspended | 2020-08-18 13:52:24
1  | started   | 2020-08-18 13:57:21
1  | suspended | 2020-08-18 13:57:22
1  | started   | 2020-08-18 15:07:56
1  | suspended | 2020-08-18 15:08:56
1  | started   | 2020-08-18 15:09:11
1  | suspended | 2020-08-18 15:09:11
1  | started   | 2020-08-18 15:09:11
1  | suspended | 2020-08-18 15:09:13

Expected result:

--------------------------------------
id | action    | date
--------------------------------------
1  | started   | 2020-08-18 13:51:02
1  | suspended | 2020-08-18 13:52:24
1  | started   | 2020-08-18 13:57:21
1  | suspended | 2020-08-18 13:57:22
1  | started   | 2020-08-18 15:07:56
1  | suspended | 2020-08-18 15:09:13

I will be very grateful for your help!

Best Answer

As I mentioned in my comment, your request is not well defined because it is unclear how the 4-minute wide time windows are supposed to be chosen. In addition, the nature and importance of the id column is unclear.

Be that as it may, I came up with the following query. It uses window functions in order to define the group edges, and then filters out any row that is not an edge:

WITH t AS (
    SELECT id, action, date
         , min(date) OVER (PARTITION BY round(extract(epoch FROM date)/240)) min_date
         , max(date) OVER (PARTITION BY round(extract(epoch FROM date)/240)) max_date
    FROM tab
)
SELECT id, action, date
FROM t
WHERE date = min_date OR date = max_date;