如何为数千和数百万使用不同的组分隔符。甲骨文
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" 的值的分隔符)
我需要以下一种格式显示不同的结果,例如:
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)
即'
,一个 百万 分隔符
- 第 12 行 - 连接
- 第 11 行 - 反向连接 "reversed" 字符串
- 第 10 行 - 从结果的开头删除可能的非数字字符(这些字符是短于 "thousand" 或 "million" 的值的分隔符)