How to group timestamps into islands (based on arbitrary gap)?

SELECT done, count(*) FILTER (WHERE step) OVER (ORDER BY done) AS grp
FROM  (
   SELECT done
        , lag(done) OVER (ORDER BY done) <= done - interval '2 min' AS step
   FROM   tbl
   ) sub
ORDER  BY done;

The subquery sub returns step = true if the previous row is at least 2 min away – sorted by the timestamp column done itself in this case.

The outer query adds a rolling count of steps, effectively the group number (grp) – combining the aggregate FILTER clause with another window function.

fiddle

Related:

About the aggregate FILTER clause:

Leave a Comment