Reputation: 3816
I have following strings:
with strlist as (
select '#RH1#RH1-GEN#RH1-GEN-RW1' col from dual
union all
select '#RH1#RH1-GEN#RH1-GEN-RW1#RH1-GEN-RW1-RRWA' col from dual
union all
select '#RH1' col from dual
)
select * from strlist
Desired out put is
COL1 COL2 COL3 COL4
RH1 RH1-GEN RH1-GEN-RW1 NULL
RH1 RH1-GEN RH1-GEN-RW1 RH1-GEN-RW1-RRWA
RH1 NULL NULL NULL
Is there an easy way for this?
I tried below.. with few exceptions its working. But am looking for a better/accurate alternative:
with strlist as (
select '#RH1#RH1-GEN#RH1-GEN-RW1' FULLPATH from dual
union all
select '#RH1#RH1-GEN#RH1-GEN-RW1#RH1-GEN-RW1-RRWA' FULLPATH from dual
union all
select '#RH1' FULLPATH from dual
)
select FULLPATH,
SUBSTR (FULLPATH, 1, REGEXP_INSTR(FULLPATH, '(#)+', 1, 2)) PHASE,
SUBSTR (FULLPATH, REGEXP_INSTR(FULLPATH, '(#)+', 1, 2), REGEXP_INSTR(FULLPATH, '(#)+', 1, 3) - REGEXP_INSTR(FULLPATH, '(#)+', 1, 2)) AREA,
SUBSTR (FULLPATH, REGEXP_INSTR(FULLPATH, '(#)+', 1, 3), REGEXP_INSTR(FULLPATH, '(#)+', 1, 4) - REGEXP_INSTR(FULLPATH, '(#)+', 1, 3)) AREA,
SUBSTR (FULLPATH, REGEXP_INSTR(FULLPATH, '(#)+', 1, 4), REGEXP_INSTR(FULLPATH, '(#)+', 1, 5) - REGEXP_INSTR(FULLPATH, '(#)+', 1, 4)) SYSTEM,
SUBSTR (FULLPATH, -REGEXP_INSTR(FULLPATH, '(#)+', 1, 5)) TAG
from strlist
Upvotes: 0
Views: 72
Reputation: 10360
This version allows for NULL list elements as shown in the last string.
SQL> with strlist(col) as (
select '#RH1##RH1-GEN-RW1' from dual union
select '#RH1#RH1-GEN#RH1-GEN-RW1#RH1-GEN-RW1-RRWA' from dual union
select '#RH1' from dual union
select '#RH1##RH1-GEN-RW1#RH1-GEN-RW1-RRWA' from dual
)
select
regexp_substr(col, '(.*?)(#|$)', 1, 2, NULL, 1) col1,
regexp_substr(col, '(.*?)(#|$)', 1, 3, NULL, 1) col2,
regexp_substr(col, '(.*?)(#|$)', 1, 4, NULL, 1) col3,
regexp_substr(col, '(.*?)(#|$)', 1, 5, NULL, 1) col4
from strlist;
COL1 COL2 COL3 COL4
---------- ---------- -------------------- --------------------
RH1
RH1 RH1-GEN-RW1
RH1 RH1-GEN-RW1 RH1-GEN-RW1-RRWA
RH1 RH1-GEN RH1-GEN-RW1 RH1-GEN-RW1-RRWA
SQL>
NOTE! Regular expressions of the format '[^#]+'
often used to split strings DO NOT HANDLE NULL ELEMENTS! See here for more info: https://stackoverflow.com/a/31464699/2543416. Get out of the habit of using that format lest your queries one day start returning the wrong data (I actually found this situation so now I'm on a mission)!
Upvotes: 2
Reputation: 6346
with strlist
as (select '#RH1#RH1#GEN#RH1-GEN-RW1' FULLPATH from dual
union all
select '#RH1#RH1-GEN#RH1-GEN-RW1#RH1-GEN-RW1-RRWA' FULLPATH from dual
union all
select '#RH1' FULLPATH from dual)
select *
from strlist
, xmltable('let $i := 0 return <list> {for $i in tokenize($in,",") return <col>{$i}</col>} </list>'
passing replace(FULLPATH, '#', ',') as "in"
columns col1 varchar2(100) path '//list/col[2]/text()'
, col2 varchar2(100) path '//list/col[3]/text()'
, col3 varchar2(100) path '//list/col[4]/text()'
, col4 varchar2(100) path '//list/col[5]/text()');
If you need more columns just add next one. There is a small trick in code. Because for xuqery char "#" is special. I have to replace it with somthing else .",".
Upvotes: 3
Reputation: 42753
If Maximum 5 separators
, then try this:
with strlist as (
select '#RH1#RH1-GEN#RH1-GEN-RW1' col from dual
union all
select '#RH1#RH1-GEN#RH1-GEN-RW1#RH1-GEN-RW1-RRWA' col from dual
union all
select '#RH1' col from dual
)
SELECT
REGEXP_SUBSTR(col, '[^#]+', 1, 1) col1,
REGEXP_SUBSTR(col, '[^#]+', 1, 2) col2,
REGEXP_SUBSTR(col, '[^#]+', 1, 3) col3,
REGEXP_SUBSTR(col, '[^#]+', 1, 4) col4,
REGEXP_SUBSTR(col, '[^#]+', 1, 5) col5
FROM strlist;
Upvotes: 1