2

使用 Oracle 11g,如果小数的值为 0,我想解析一个数字以去除小数,如果小数的值不同于 0,则在小数分隔符 ',' 后保留两个小数

例子:

1,00 -> 1
1,001 -> 1
0,203 -> 0,20

等等。

我以一种非常不雅的方式获得了类似的东西

select replace(trim(to_char (trunc ('0,2345',2),'9999999990.99')), '.', ',')
from dual

你知道更优雅的方式吗?输出应该是一个字符(不是数字)。

4

3 回答 3

1

不确定它是否更优雅,但假设您的替换是处理不同的语言环境,这可能对您有用:

with t as (
  select 1.00 as n from dual
  union all select 1.001 from dual
  union all select 0.203 from dual
  union all select 0.2345 from dual
  union all select 112.999 from dual
)
select n, regexp_replace(to_char(trunc(n, 2), '9999999990D00',
  'NLS_NUMERIC_CHARACTERS='',.'''), '[,.]00$', null) as new_n
from t;

         N NEW_N        
---------- --------------
         1           1    
     1.001           1    
     0.203           0,20 
    0.2345           0,23 
   112.999         112,99 

让您指定它是使用逗号还是句点作为小数分隔符的参数nls_paramto_char如果您可以在会话级别设置它,那么查询看起来会更简单一些。字符串末尾的regexp_replace条带,00(或.00,认为它是矫枉过正的)。


正如 ThinkJet 所指出的regexp_replace,这有点过分,并且由于小数分隔符是在列中定义的(并且格式无论如何都没有组分隔符),因此可以通过计划来完成replace

with t as (
  select 1.00 as n from dual
  union all select 1.001 from dual
  union all select 0.203 from dual
  union all select 0.2345 from dual
  union all select 112.999 from dual
  union all select 13.08 from dual
)
select n, replace(trim(
    to_char(trunc(n, 2), '9999999990D00', 'NLS_NUMERIC_CHARACTERS='',.''')),
    ',00', null) as new_n
from t;

         N NEW_N        
---------- --------------
         1 1              
     1.001 1              
     0.203 0,20           
    0.2345 0,23           
   112.999 112,99         
     13.08 13,08          

不过,仍然不确定这是否可以被描述为“优雅”。

于 2013-07-24T09:48:22.057 回答
1

另一种变体

SELECT n,
      to_char( trunc( n, 2 ), 
               case when mod( trunc( n, 2 ), 1 ) = 0
                    then '9990' 
                    else '9990D00'
               end, 'NLS_NUMERIC_CHARACTERS='',.''' ) val
from t
;


SQLFiddle 演示

于 2013-07-25T20:10:57.933 回答
1

要获得正确的结果,您必须处理数字,而不是字符串:

with t as (
  select 1.00 as n from dual
  union all select 1.001 from dual
  union all select 0.203 from dual
  union all select 0.2345 from dual
  union all select 112.999 from dual
  union all select 112.105 from dual
  union all select 0 from dual
  union all select -12.307 from dual
)
select
  n,
  decode( trunc(n,2) - trunc(n) , 
    0, to_char(trunc(n), 'TM9', 'NLS_NUMERIC_CHARACTERS = '', '''),
    to_char(trunc(n,2),'9999999990D00', 'NLS_NUMERIC_CHARACTERS = '', ''')
  ) 
    string_val  
from t

SQLFiddle

PS 更新以获取不正确的截断而不是舍入,如 OP 请求中所示。

于 2013-07-24T13:35:28.660 回答