Вы можете использовать совокупный счет. Эта версия включает 4-е вхождение:
select t.*
from (select t.*,
count(*) filter (where event_id = 11) over (partition by user_id order by timestamp) as event_11_cnt
from t
) t
where event_11_cnt >= 4;
Синтаксис filter
долгое время действовал Postgres, но вместо этого вы можете использовать:
select t.*
from (select t.*,
sum( (event_id = 11)::int ) over (partition by user_id order by timestamp) as event_11_cnt
from t
) t
where event_11_cnt >= 4;
Эта версия не:
where event_11_cnt > 4 or (event_11_cnt = 4 and event_id <> 11)
Альтернативный метод:
select t.*
from t
where t.timestamp > (select t2.timestamp
from t t2
where t2.user_id = t.user_id and
t2.event_id = 11
order by t2.timestamp
limit 1 offset 3
);