Oracle - 如何使用WITH子句将字符串转换为行对

时间:2014-02-09 09:40:31

标签: regex oracle

在其中一个栏目中,我有角色和组织职位 示例位置为1,组织为310492 ...

1|310492|1|12319|1|562548|1|5202558

我需要将此字符串转换为多行

1,310492
1,12319
1,562548
1,5202558

我不能使用WITH子句,因为我需要具有相关的子查询

SELECT   EXTRACT (VALUE (d), '//row/text()').getstringval () 
  FROM (SELECT XMLTYPE (   '<rows><row>' || REPLACE (USERPROF.FIELD1, '|', '</row><row>') || '</row></rows>'  ) AS xmlval FROM USERPROF WHERE FIELD1 IS NOT NULL   ) x, TABLE (XMLSEQUENCE (EXTRACT (x.xmlval, '/rows/row'))) d

但是这会将整个字符串转换为多行。

我尝试使用regexp和connect来帮助我,但是通过忽略where条件来获取整个表的内容。

 select regexp_substr(FIELD1,'[^|]+', 1, LEVEL) from USERPROF WHERE USERS_ID = 23502
   connect by regexp_substr(FIELD1, '[^|]+', 1, level ) is not null;

提前致谢。

1 个答案:

答案 0 :(得分:0)

下面的SQL:

with data as
(select '1|310492|1|12319|1|562548|1|5202558' as x from dual)
select fin from(
    select          1+level-1 as occurrence
                    , instr(x,'|',1,1+level-1) as pos
                    , nvl(lead(instr(x,'|',1,1+level-1),1) over (order by 1+level-1)
                        , length(x))
                        as xxxx
                    ,   case when 
                                    nvl(lead(instr(x,'|',1,1+level-1),1) over (order by 1+level-1)
                                        , length(x)) = length(x)
                                        then instr(x,'|',1,1+level-1)
                                        else
                        nvl(lag(instr(x,'|',1,1+level-1),1) over (order by 1+level-1),1) end as yyyy
                    , substr(x
                              ,case when 
                                    nvl(lead(instr(x,'|',1,1+level-1),1) over (order by 1+level-1)
                                        , length(x)) = length(x)
                                        then instr(x,'|',1,1+level-1)
                                        else
                        nvl(lag(instr(x,'|',1,1+level-1),1) over (order by 1+level-1),1) end
                              ,nvl(lead(instr(x,'|',1,1+level-1),1) over (order by 1+level-1)
                        , length(x))
                                - case when 
                                    nvl(lead(instr(x,'|',1,1+level-1),1) over (order by 1+level-1)
                                        , length(x)) = length(x)
                                        then instr(x,'|',1,1+level-1)
                                        else
                        nvl(lag(instr(x,'|',1,1+level-1),1) over (order by 1+level-1),1) end
                              ) as fin
                      , length(x) as lastrw
    from data
    connect by level <= length(x) - length(replace(x, '|')) - 1
    order by 1) x
where mod(occurrence,2) = 1 or xxxx = lastrw

结果:

FIN
1|310492
|1|12319
|1|562548
|1|520255

请注意,我只是使用with子句来使用您提供的数据作为示例。