Возможно, более простой способ, но это может помочь начать. Я запустил его на Postgres, но должен работать (возможно, с небольшой настройкой) на Oracle. Самый внутренний запрос помещает предыдущее значение в каждую строку. Мы можем использовать это, чтобы обнаружить изменение группировки (когда значение не равно предыдущему значению). Каждый раз, когда происходит смена группы, мы помечаем ее «1». Суммируйте эти групповые изменения, и теперь у нас есть идентификатор группы, который увеличивается каждый раз, когда происходит изменение значения. Тогда мы можем выполнить нашу нормальную группу по функции.
create table x(id int, value varchar(1));
insert into x values(1, 'a');
insert into x values(2, 'b');
insert into x values(3, 'b');
insert into x values(4, 'b');
insert into x values(5, 'a');
insert into x values(6, 'a');
insert into x values(7, 'b');
insert into x values(8, 'b');
SELECT MIN(id), MAX(id), value
FROM ( SELECT id
,value
,previous_value
,SUM( CASE WHEN value = previous_value THEN 0 ELSE 1 END ) OVER(ORDER BY id) AS group_id
FROM ( SELECT id
,value
,COALESCE( LAG(value) OVER(ORDER BY id), value ) previous_value
FROM x
ORDER BY id
) y
) z
GROUP BY group_id, value
ORDER BY 1, 2;
min | max | value
-----+-----+-------
1 | 1 | a
2 | 4 | b
5 | 6 | a
7 | 8 | b
(4 rows)