Esta solução funciona com um número arbitrário de colunas (largura, altura, ...) e valores.
-- your test data
with data(val) as
(select 'Width:10|7|20|45,Height:25|5|6|45,Length:35|6|3|4' from dual),
-- split by ,
cols as
(select regexp_substr(str, '[^,]+', 1, level) val
from (select val as str from data)
connect by regexp_substr((select val as str from data),
'[^,]+',
1,
level) is not null),
-- split by :
hdr_and_cols as
(select substr(val, 1, instr(val, ':') - 1) as hdr,
substr(val, instr(val, ':') + 1) as val
from cols),
-- split by |
hdr_lvl_vals as
(select distinct x.hdr,
level as entry,
regexp_substr(x.val, '[^|]+', 1, level) as val
from hdr_and_cols x
connect by regexp_substr(x.val, '[^|]+', 1, level) is not null)
select * from hdr_lvl_vals;
Resultado:
hdr entry value
---------------------
Height 1 25
Height 2 5
Height 3 6
Height 4 45
Length 1 35
Length 2 6
Length 3 3
Length 4 4
Width 1 10
Width 2 7
Width 3 20
Width 4 45
Você pode formatar o resultado da maneira que desejar, por exemplo.
-- your test data
with data(val) as
(select 'Width:10|7|20|45,Height:25|5|6|45,Length:35|6|3|4' from dual),
-- split by ,
cols as
(select regexp_substr(str, '[^,]+', 1, level) val
from (select val as str from data)
connect by regexp_substr((select val as str from data),
'[^,]+',
1,
level) is not null),
-- split by :
hdr_and_cols as
(select substr(val, 1, instr(val, ':') - 1) as hdr,
substr(val, instr(val, ':') + 1) as val
from cols),
-- split by |
hdr_lvl_vals as
(select distinct x.hdr,
level as entry,
regexp_substr(x.val, '[^|]+', 1, level) as val
from hdr_and_cols x
connect by regexp_substr(x.val, '[^|]+', 1, level) is not null)
-- format output
select w.val as width, h.val as heigth, l.val as length
from (select entry, val from hdr_lvl_vals where hdr = 'Width') w,
(select entry, val from hdr_lvl_vals where hdr = 'Height') h,
(select entry, val from hdr_lvl_vals where hdr = 'Length') l,
(select level as entry
from dual
connect by level <= (select max(entry) from hdr_lvl_vals)) r
where r.entry = w.entry
and r.entry = h.entry
and r.entry = l.entry;
Resultado:
WIDTH HEIGTH LENGTH
--------------------
10 25 35
7 5 6
20 6 3
45 45 4