您可以通過分層查詢做到這一點:
with w1(list) as
(
select '[1..5],[8..12],15,16' from dual
union all
select '17,18' from dual
union all
select '[21..45]' from dual
),
w2 as
(
select distinct w1.list, regexp_substr(w1.list, '[^,]+', 1, level) part
from w1
connect by regexp_instr(w1.list, '[^,]+', 1, level) != 0
order by w1.list
),
w3 as
(
select w2.*,
regexp_replace(w2.part, '\[(\d+)\.\.(\d+)]', '\1', 1) lower_bound,
regexp_replace(w2.part, '\[(\d+)\.\.(\d+)]', '\2', 1) upper_bound
from w2
)
select distinct w3.*, w3.lower_bound + level - 1 item
from w3
connect by level <= w3.upper_bound - w3.lower_bound + 1
order by 1, 5
;
這給:
LIST PART LOWER_BOUND UPPER_BOUND ITEM
17,18 17 17 17 17
17,18 18 18 18 18
[1..5],[8..12],15,16 [1..5] 1 5 1
[1..5],[8..12],15,16 [1..5] 1 5 2
[1..5],[8..12],15,16 [1..5] 1 5 3
[1..5],[8..12],15,16 [1..5] 1 5 4
[1..5],[8..12],15,16 [1..5] 1 5 5
[1..5],[8..12],15,16 [8..12] 8 12 8
[1..5],[8..12],15,16 [8..12] 8 12 9
[1..5],[8..12],15,16 [8..12] 8 12 10
[1..5],[8..12],15,16 [8..12] 8 12 11
[1..5],[8..12],15,16 [8..12] 8 12 12
[1..5],[8..12],15,16 15 15 15 15
[1..5],[8..12],15,16 16 16 16 16
[21..45] [21..45] 21 45 21
[21..45] [21..45] 21 45 22
[21..45] [21..45] 21 45 23
[21..45] [21..45] 21 45 24
[21..45] [21..45] 21 45 25
[21..45] [21..45] 21 45 26
[21..45] [21..45] 21 45 27
[21..45] [21..45] 21 45 28
[21..45] [21..45] 21 45 29
[21..45] [21..45] 21 45 30
[21..45] [21..45] 21 45 31
[21..45] [21..45] 21 45 32
[21..45] [21..45] 21 45 33
[21..45] [21..45] 21 45 34
[21..45] [21..45] 21 45 35
[21..45] [21..45] 21 45 36
[21..45] [21..45] 21 45 37
[21..45] [21..45] 21 45 38
[21..45] [21..45] 21 45 39
[21..45] [21..45] 21 45 40
[21..45] [21..45] 21 45 41
[21..45] [21..45] 21 45 42
[21..45] [21..45] 21 45 43
[21..45] [21..45] 21 45 44
[21..45] [21..45] 21 45 45
您的樣本數據沒有道理。我建議你在這裏提供一個SQLFiddle或至少格式。 – KrazzyNefarious