Один вариант использует рекурсивный запрос. Начиная с 11gR2, Oracle поддерживает стандартные рекурсивные общие табличные выражения, поэтому вы можете сделать:
with cte(id, field_1, field_2, max_field_1, max_field_2) as (
select
id,
to_number(regexp_substr(field_1, '^\d+')),
to_number(regexp_substr(field_2, '^\d+')),
to_number(regexp_substr(field_1, '\d+$')),
to_number(regexp_substr(field_2, '\d+$'))
from mytable
union all
select
id,
field_1 + 1,
field_2 + 1,
max_field_1,
max_field_2
from cte
where field_1 < max_field_1
)
select id, field_1, field_2 from cte order by id, field_1
Это предполагает, что интервалы в одной и той же строке всегда имеют одинаковую длину, как показано в ваших данных примера. Если это не так, объясните, как вы хотите с этим справиться.
Демонстрация на DB Fiddle :
ID | FIELD_1 | FIELD_2
-: | ------: | ------:
1 | 1 | 1
1 | 2 | 2
1 | 3 | 3
1 | 4 | 4
1 | 5 | 5
1 | 20 | 55
1 | 21 | 56
1 | 22 | 57
1 | 23 | 58
1 | 24 | 59
1 | 25 | 60
1 | 26 | 61
1 | 27 | 62
1 | 28 | 63
1 | 29 | 64
1 | 30 | 65
2 | 1 | 10
2 | 2 | 11
2 | 3 | 12
2 | 4 | 13
2 | 5 | 14
2 | 6 | 15
2 | 7 | 16
2 | 8 | 17
2 | 66 | 80
2 | 67 | 81
2 | 68 | 82
2 | 69 | 83
2 | 70 | 84
2 | 71 | 85
2 | 72 | 86