Oracleで、先頭に0を付けた数字を文字に変換するとき、whyは先頭の数字が消えますか?このロジックはOracle固有ですか、それともSQL固有ですか?
例:
SELECT TO_CHAR(0.56) FROM DUAL;
/* Result = .56 */
私は、先頭または末尾なしで数値をフォーマットする方法を探していました スペース 、ピリオド、ゼロ(存在するはずの1より小さい数値の先頭のゼロを除く)。
これは、このような最も一般的な書式設定をOracleで簡単に実現できないことを不満に思っています。
でも Tom Kyteは長く複雑な回避策のみを提案した このように:
case when trunc(x)=x
then to_char(x, 'FM999999999999999999')
else to_char(x, 'FM999999999999999.99')
end x
しかし、私は一度だけ値に言及するより短いソリューションを見つけることができました:
rtrim(to_char(x, 'FM999999999999990.99'), '.')
これ 期待どおりに動作します すべての可能な値に対して:
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;
しかし、 カスタムpl/sql関数には大きなパフォーマンスオーバーヘッドがあります これは、大量のクエリには適していません。
きれいな(私にとって)形式で10進数を取得する唯一の方法は、とんでもないコードを必要とするようです。
私がこれまでに得た唯一の解決策:
CASE WHEN xy>0 and xy<1 then '0' || to_char(xy) else to_char(xy)
xy
は10進数です。
xy query result
0.8 0.8 --not sth like .80
10 10 --not sth like 10.00
このための実際のフォーマットオプションがある場合は、この質問に答えてください。
これは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の提案に対するコメントとして追加したかったのですが、できません。
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);
すべての場合に機能するはずです:
SELECT regexp_replace(0.1234, '^(-?)([.,])', '\10\2') FROM dual