如何使用成千上万的不同组分隔符。甲骨文

时间:2019-10-26 04:35:17

标签: oracle regexp-replace

我需要以下一种格式显示不同的结果,例如:

40000000至40'000,000

我尝试使用此方法,但是当我尝试2个不同的组分隔符时,出现“无效的数字格式模型”错误:

select to_char(9999999999, '9g999g99999g9', 'NLS_NUMERIC_CHARACTERS='',.''')
from dual;

也尝试使用substr和replace,但是在所有情况下都不起作用(例如结果为3000000或700000000时)。 这可行,但不是最佳解决方案。

SELECT substr(replace('40,000,000',',',''''),0,length(40000000)-2)|| substr('40,000,000',-4) from dual; 

如果我使用前面的代码,实际选择会是什么样子。

SELECT substr(replace(to_char(oTOTAL_SENIOR, '999,999,999'),',',''''),0,length(oTOTAL_SENIOR)-2)|| substr(to_char(oTOTAL_SENIOR, '999,999,999'),-4) from dual

由于“ 999,999,999”,当我同时使用substr replace和to_char时,以前的选择被错误了。

我也尝试使用regexp_replace,但是我不擅长。 我知道我需要替换除最后4个字符(000个)以外的所有内容,但我不知道如何。

任何帮助都会得到赞赏。

1 个答案:

答案 0 :(得分:0)

您需要比我更聪明的人来正确执行此操作,但是-同时查看是否有帮助。

我正在使用XE 11g;为了避免在此查询的最后步骤中出现“没有更多数据可从套接字读取”错误(我相信这是由于两个字符串反转),我创建了自己的“反转”函数。有 undocumented reverse函数,但我不想使用它。

基本上,它会反转您作为参数传递的字符串。我需要什么?我发现反转值,将它们拆分为3×3×3字符并应用所需的“奇怪”分隔符更加简单。另外,它使整个代码更简单。没有它也可以完成,但是-正如我所说-没有更多的数据可以从套接字读取。抱歉。

现在,有人会说:您为什么不(完全是我,LF)完全使用PL / SQL并将一切放入函数中呢?不需要特殊原因,也没有问题。

好的,这里是:

SQL> create or replace function f_reverse (par_string in varchar2)
  2    return varchar2
  3  is
  4    retval varchar2(20);
  5  begin
  6    select listagg(substr(par_string, level, 1))
  7           within group (order by level desc)
  8      into retval
  9      from dual
 10      connect by level <= length(par_string);
 11
 12    return retval;
 13  end;
 14  /

Function created.

SQL> select f_reverse('1234') from dual;

F_REVERSE('1234')
---------------------------------------------------------------------
4321

SQL>

最后,这就是您想要的:

SQL> with test (id, col) as
  2    (select 1, 40100200 from dual union all
  3     select 2,  2300400 from dual union all
  4     select 3,   700500 from dual union all
  5     select 4,    25700 from dual union all
  6     select 5,     6300 from dual union all
  7     select 6,      555 from dual
  8    )
  9  select id,
 10    regexp_replace(
 11                    f_reverse(
 12                      substr(f_reverse(col), 1, 3) ||','||
 13                      substr(f_reverse(col), 4, 3) || chr(39) ||
 14                      substr(f_reverse(col), 7)
 15                      ), '^[^0-9]+', '') result
 16  from test;

        ID RESULT
---------- ----------
         1 40'100,200
         2 2'300,400
         3 700,500
         4 25,700
         5 6,300
         6 555

6 rows selected.

SQL>

它是做什么的?

  • 第1-7行-样本数据
  • 第9行起是有用的代码
  • 第12-14行-将反向采样数据拆分为长度为3个字符的子字符串
    • 第12行-级联,,因为这是分隔符
    • 第13行-串联的chr(13) ',是一个百万个分隔符
  • 第11行-反向连接串联的“反向”字符串
  • 第10行-从结果开头删除可能的非数字字符(这些字符是小于“千”或“百万”的值的分隔符)