souki-paranoiastのブログ

地方都市でプログラマーをやっている人のブログ。技術ネタ以外も少し書く。メインの言語はJava。https://paranoiastudio-japan.jimdo.com/ に所属

【PostgreSQL】小数点以下のみ固定長フォーマットを施す

やりたいことは表題通り。外部アプリとの連携でそういう値が求められた。 つまり、

1.1
0.2
123
0.123456

は、それぞれ

1.100
0.200
123.000
0.123

となる必要がある感じ。 …ニッチなケースだなぁ。

基本的な記述は下記の通りで良いはず。

select to_char(n, ('FMMI9990.000'))

ただ、これだと整数部分の桁が超過した場合などが、####.###みたいな結果値になってしまい残念。フォーマット文字列の9が多い分には問題ないみたいだが。

そのため、動的にやるしかないと思う。もっと良い方法あるのだろうか。公式ページのto_char()の説明を読む限りではこれが最善っぽいのだが。

select to_char(n, ('FMMI'|| lpad('', length(n::text), '9') || '0.' || lpad('', 3, '0')))

テストデータ

with data(n) as (
values(null)
,(1)
,(1.2)
,(1.23)
,(1.234)
,(1.2345)
,(21.2345)
,(321.2345)
,(4321.2345)
,(54321.2345)
,(0)
,(0.2)
,(0.23)
,(0.234)
,(0.2345)
,(-1)
,(-1.2)
,(-1.23)
,(-1.234)
,(-1.2345)
,(-21.2345)
,(-321.2345)
,(-4321.2345)
,(-54321.2345)
,(-0.2)
,(-0.23)
,(-0.234)
,(-0.2345)
,(-5123456789087654321234567897654321.23456789)
,(-5123456789087654321234567897654321)
,(5123456789087654321234567897654321)
)

select n
      ,to_char(n, ('FMMI'|| lpad('', length(n::text), '9') || '0.' || lpad('', 3, '0')))
  from data

2023-11-24 追記

久しぶりにこの記事読み直したけど、これで良いじゃないか。。

select round(n, 3)::text