select
event_id, device, ts,
floor(extract(epoch from ts) / 180) as group
from t
order by ts
It is possible to make the group number a sequence starting at 1 using a window function but it is a not small cost that I don't know if is necessary. This is it
select
event_id, device, ts,
dense_rank() over(order by "group") as group
from (
select
event_id, device, ts,
floor(extract(epoch from ts) / 180) as group
from t
) s
order by ts
time
is a reserved word. Pick another one as the column name.