【问题标题】:Print all characters after every 3rd occurrence of comma in oracle在 oracle 中每隔 3 次出现逗号后打印所有字符
【发布时间】:2019-01-03 01:36:33
【问题描述】:

我有一个字符串为“12as3,45we6,7we89,101112,131415,3234,1234”,并想编写一个 oracle 正则表达式函数或 SQL 以在逗号 (,) 的每 3 次出现后打印所有字符。

所以输出应该是

12as3,45we6,7we89
101112,131415,3234
1234

我尝试了正则表达式,但它只打印第一次出现。

 SELECT NVL(
  SUBSTR('12as3,45we6,7we89,101112,131415,3234,1234', 1,
  INSTR('12as3,45we6,7we89,101112,131415,3234,1234',',',1,3) -1),
 '12as3,45we6,7we89,101112,131415,3234,1234')
FROM dual;

输出是 12as3,45we6,7we89

我也试过这个,但它在每个逗号后打印。

with t as (
       select '12as3,45we6,7we89,101112,131415,3234,1234' as str from dual
      )
select  extractvalue(value(x), '/b') x
from  t,
    table(
          xmlsequence(
                      xmltype('<a><b>' || replace(str, ',', '</b><b>') || 
 '</b></a>' ).extract('/*/*')
                     )
             ) x
    /

有什么办法不使用函数过程,我们可以在Oracle中写一个select语句。

【问题讨论】:

  • 不要在您的表中存储这样的 CSV 数据。您在这里需要的是正则表达式拆分,以打破任意行数的单个记录。我不知道该怎么做。

标签: xml oracle oracle11g


【解决方案1】:

这是一个使用函数的选项。

想法是:

  • 将输入字符串拆分成行
  • 将它的片段(它是一个)连接成一个组中的 3 个,用逗号分隔
  • 如果是第三部分(见MOD函数),用换行符分隔它们(CHR(10))(它是分割器

SQL> create or replace function f_split (par_str in varchar2)
  2    return varchar2
  3  is
  4    l_str varchar2(200);
  5  begin
  6    for cur_r in (select mod(row_number() over (order by null), 3) rn_mod,
  7                         case when mod(row_number() over (order by null), 3) = 0 then chr(10)
  8                              else ','
  9                         end splitter,
 10                         regexp_substr(par_str, '[^,]+', 1, level) one
 11                  from dual
 12                  connect by level <= regexp_count(par_str, ',') + 1
 13                 )
 14    loop
 15      l_str := l_str || cur_r.one || cur_r.splitter;
 16    end loop;
 17
 18    return (l_str);
 19  end;
 20  /

Function created.

SQL> select f_split('12as3,45we6,7we89,101112,131415,3234,1234') result from dual;

RESULT
--------------------------------------------------------------------------------
12as3,45we6,7we89
101112,131415,3234
1234,


SQL>

为什么不使用使用相同代码的简单 SQL?正因为如此:

SQL> with test (col) as
  2    (select '12as3,45we6,7we89,101112,131415,3234,1234' from dual),
  3  split_me as
  4    (select row_number() over (order by null) rn,
  5            case when mod(row_number() over (order by null), 3) = 0 then chr(10)
  6                 else ','
  7            end splitter,
  8            regexp_substr(col, '[^,]+', 1, level) one
  9     from test
 10     connect by level <= regexp_count(col, ',') + 1
 11    )
 12  select listagg(one, splitter) within group (order by rn) result
 13  from split_me;
select listagg(one, splitter) within group (order by rn) result
                    *
ERROR at line 12:
ORA-30496: Argument should be a constant.


SQL>

我不知道如何解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多