如何为数千和数百万使用不同的组分隔符。甲骨文

How to use different group separators for thousands and millions. Oracle

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

40000000 到 40'000,000

我尝试使用这个,但是当我尝试使用 2 个不同的组分隔符时,我得到 "invalid number format model" 错误:

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 会是什么样子。

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

当我同时使用 substr replace 和 to_char 时,之前的 select 由于 '999,999,999' 而被窃听。

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

我们将不胜感激任何帮助。

你需要比我更聪明的人才能正确地做到这一点,但是 - 与此同时,看看这是否有帮助。

我在 XE 11g;为了避免在此查询的最后步骤中出现 "no more data to read from socket" 错误(我认为这是由于两次字符串反转造成的),我创建了自己的 "reverse" 函数。有 未记录 reverse 函数,但我不想使用它。

基本上,它会反转您作为参数传递的字符串。我需要它做什么?我发现反转值、将它们拆分为 3×3×3 字符并应用所需的 "strange" 分隔符更简单。此外,它还使整个代码 更简单 。它可以在没有它的情况下完成,但是 - 正如我所说 - 没有更多数据可以从套接字读取 将不允许它。抱歉。

现在,有人会说:你(意思是:我,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 行 - 反向连接 "reversed" 字符串
  • 第 10 行 - 从结果的开头删除可能的非数字字符(这些字符是短于 "thousand" 或 "million" 的值的分隔符)