在Oracle中,将带前导零的数字转换为字符时,为什么前导数字会消失?这个逻辑是Oracle特定的,还是特定于SQL的?
示例:
SELECT TO_CHAR(0.56) FROM DUAL;
/* Result = .56 */
答案 0 :(得分:31)
这是Oracle提供的默认格式。如果要在输出上使用前导零,则需要明确提供格式。使用:
SELECT TO_CHAR(0.56,'0.99') FROM DUAL;
甚至:
SELECT TO_CHAR(.56,'0.99') FROM DUAL;
尾随零也是如此:
SQL> SELECT TO_CHAR(.56,'0.990') val FROM DUAL;
VAL
------
0.560
TO_CHAR转换函数的一般形式是:
答案 1 :(得分:25)
我一直在寻找一种格式化数字的方法,不带前导或尾随spaces,句点,零(除了一个前导零,小于1的数字应该存在)。
令人沮丧的是,这种最常见的格式化在Oracle中无法轻松实现。
即使Tom Kyte only suggested long complicated workaround也是这样:
case when trunc(x)=x
then to_char(x, 'FM999999999999999999')
else to_char(x, 'FM999999999999999.99')
end x
但我能找到更短的解决方案,只提到一次价值:
rtrim(to_char(x, 'FM999999999999990.99'), '.')
此works as expected代表所有可能的值:
select
to_char(num, 'FM99.99') wrong_leading_period,
to_char(num, 'FM90.99') wrong_trailing_period,
rtrim(to_char(num, 'FM90.99'), '.') correct
from (
select num from (select 0.25 c1, 0.1 c2, 1.2 c3, 13 c4, -70 c5 from dual)
unpivot (num for dummy in (c1, c2, c3, c4, c5))
) sampledata;
| WRONG_LEADING_PERIOD | WRONG_TRAILING_PERIOD | CORRECT |
|----------------------|-----------------------|---------|
| .25 | 0.25 | 0.25 |
| .1 | 0.1 | 0.1 |
| 1.2 | 1.2 | 1.2 |
| 13. | 13. | 13 |
| -70. | -70. | -70 |
仍在寻找更短的解决方案。
自定义辅助函数有一个缩短审批:
create or replace function str(num in number) return varchar2
as
begin
return rtrim(to_char(num, 'FM999999999999990.99'), '.');
end;
但custom pl/sql functions have significant performace overhead不适合重度查询。
答案 2 :(得分:6)
似乎在漂亮(对我来说)形式中获取小数的唯一方法需要一些荒谬的代码。
我到目前为止唯一的解决方案:
CASE WHEN xy>0 and xy<1 then '0' || to_char(xy) else to_char(xy)
xy
是一个十分之一。
xy query result
0.8 0.8 --not sth like .80
10 10 --not sth like 10.00
如果有真实的格式选项,请回答此问题。
答案 3 :(得分:4)
仅适用于小于1的数字。
select to_char(12.34, '0D99') from dual;
-- Result: #####
这不会奏效。
你可以做这样的事情,但这导致领先的空白:
select to_char(12.34, '999990D99') from dual;
-- Result: ' 12,34'
最终,你可以添加一个TRIM来再次摆脱空白,但我也不会认为这是一个合适的解决方案...
select trim(to_char(12.34, '999990D99')) from dual;
-- Result: 12,34
同样,这仅适用于最多6位数的数字
编辑:我想将此添加为对DCookie建议的评论,但我不能。
答案 4 :(得分:1)
尝试这样做以避免to_char限制:
SELECT
regexp_replace(regexp_replace(n,'^-\'||s,'-0'||s),'^\'||s,'0'||s)
FROM (SELECT -0.89 n,RTrim(1/2,5) s FROM dual);
答案 5 :(得分:0)
在所有情况下均应起作用:
SELECT regexp_replace(0.1234, '^(-?)([.,])', '\10\2') FROM dual
答案 6 :(得分:0)
在以下格式下尝试数字是否为
ex 1假设数字如10.1,如果采用以下格式,它将为10.10
ex 2假设数字如.02,如果应用以下格式,它将为0.02
ex 3假设数字为0.2,如果采用以下格式,则为0.20
to_char(舍入(to_number(列名)/ 10000000,2),'999999999990D99')作为列名