This is a [tag:gaps-and-islands] problem. Assuming there are no gaps or duplicates in the same `id_set` set: WITH partitioned AS ( SELECT *, number - ROW_NUMBER() OVER (PARTITION BY id_set) AS grp FROM atable WHERE status = 'FREE' ), counted AS ( SELECT *, COUNT(*) OVER (PARTITION BY id_set, grp) AS cnt FROM partitioned ) SELECT id_set, number FROM counted WHERE cnt >= 3 ; Here's a SQL Fiddle demo link for this query: http://sqlfiddle.com/#!12/59db6/1. [2]: http://sqlfiddle.com/#!12/b1b39/5