Grouping categorical values in a sequence
Using value_1 to order the row, you can make groups every time name changes.

Then use this groups to get max and min values.




select name, min(v1) v1, max(v2) v2
from (select name, v1, v2,
             sum(rst) over (order by v1) grp
      from (select name, v1, v2,
                   case when coalesce(lag(name) over (order by v1), '') &lt;&gt; name then 1 end rst
            from cat
            ) y
      ) z
group by name, grp
order by v1;



name | v1 | v2
:--- | -: | -:
John |  1 |  9
Mike |  9 | 17
John | 17 | 25
Dave | 25 | 29



dbfiddle here