SUBSTR 在 oracle 中添加值

SUBSTR to ADD value in oracle

我 table 的列在 Oracle DB 中具有以下格式的数据。

COL 1
abc,mno:EMP
xyz:EMP;tyu,opr:PROF
abc,mno:EMP;tyu,opr:PROF

我正在尝试将数据转换为以下格式

COL 1
abc:EMP;mno:EMP
xyz:EMP;tyu:PROF;opr:PROF
abc:EMP;mno:EMP;tyu:PROF;opr:PROF

基本上是尝试获取 : 之后和之前的所有内容;移动它用它代替逗号。

我尝试了一些 SUBSTR 和 LISTAGG,但没有得到任何值得分享的东西。

此致。

这是一种选择;阅读代码中的注释。

SQL> with test (id, col) as
  2    -- sample data
  3    (select 1, 'abc,mno:EMP'              from dual union all
  4     select 2, 'xyz:EMP;tyu,opr:PROF'     from dual union all
  5     select 3, 'abc,mno:EMP;tyu,opr:PROF' from dual
  6    ),
  7  temp as
  8    -- split sample data to rows
  9    (select id,
 10       column_value cv,
 11       regexp_substr(col, '[^;]+', 1, column_value) val
 12     from test cross join
 13       table(cast(multiset(select level from dual
 14                           connect by level <= regexp_count(col, ';') + 1
 15                          ) as sys.odcinumberlist))
 16    )
 17  -- finally, replace comma with a string that follows a colon sign
 18  select id,
 19    listagg(replace(val, ',', substr(val, instr(val, ':')) ||';'), ';') within group (order by cv) new_val
 20  from temp
 21  group by id
 22  order by id;

        ID NEW_VAL
---------- ----------------------------------------
         1 abc:EMP;mno:EMP
         2 xyz:EMP;tyu:PROF;opr:PROF
         3 abc:EMP;mno:EMP;tyu:PROF;opr:PROF

SQL>

使用 littlefoot 的答案,如果我要使用交叉应用,我将不需要转换为多重集...

with test (id, col) as
      -- sample data
      (select 1, 'abc,mno:EMP'              from dual union all
       select 2, 'xyz:EMP;tyu,opr:PROF'     from dual union all
       select 3, 'abc,mno:EMP;tyu,opr:PROF' from dual
      ),
    temp as
      -- split sample data to rows
      (select id,
              column_value cv,
              regexp_substr(col, '[^;]+', 1, column_value) val
        from test 
        cross apply (select level as column_value
                       from dual
                      connect by level<= regexp_count(col, ';') + 1)       
     )
   -- finally, replace comma with a string that follows a colon sign
   select id,
          listagg(replace(val, ',', substr(val, instr(val, ':')) ||';'), ';') within group (order by cv) new_val
     from temp
   group by id
   order by id;

你不需要递归任何东西,只需要基本的正则表达式:如果模式总是 something,something2:someCode(例如你在逗号前没有冒号),那么就足够了。

with test (id, col) as (
  select 1, 'abc,mno:EMP'              from dual union all
  select 2, 'xyz:EMP;tyu,opr:PROF'     from dual union all
  select 3, 'abc,mno:EMP;tyu,opr:PROF' from dual union all
  select 3, 'abc,mno:EMP;tyu,opr:PROF;something:QWE;something2:QWE' from dual
)
select
  /*
    Grab this groups:
    1) Everything before the comma
    2) Then everything before the colon
    3) And then everything between the colon and a semicolon
    
    Then place group 3 between 1 and 2
  */
  trim(trailing ';' from regexp_replace(col || ';', '([^,]+),([^:]+):([^;]+)', ':;:')) as res
from test
| RES                                                            |
| :------------------------------------------------------------- |
| abc:EMP;mno:EMP                                                |
| xyz:EMP;tyu:PROF;opr:PROF                                      |
| abc:EMP;mno:EMP;tyu:PROF;opr:PROF                              |
| abc:EMP;mno:EMP;tyu:PROF;opr:PROF;something:QWE;something2:QWE |

db<>fiddle here