読者です 読者をやめる 読者になる 読者になる

数値の桁を制限した上で右寄せ (SQL Server 2005)

なんか numeric とか使うと、小数点以下の桁数指定しても無駄に 0 が出るアプリケーションでの話。
それはいやだということで、A さんが STR 関数使って、

SELECT STR(col, 16, 1) FROM ...;

みたいにしてたんだけど、これだとそのアプリケーションでは左寄せになってしまい、小数点の位置がそろわないと文句が・・・
A さんが無理だと投げたので、仕事がなくて遊んでいた真面目に仕事していた俺が対応することに。
最初は「左に空白何文字か詰めればいいんじゃねーの?」と考えてたんだけど、なんとそのアプリケーションはおせっかいにも素晴らしいことに、左右の空白文字を削除してくれるのでした。
で、出した結論がこれ。

DECLARE @max_len AS int;
SELECT @max_len = LEN(LTRIM(STR(MAX(col), 16, 1))) FROM ...;

SELECT
    -- 2倍してるのはアプリケーション側がスペース2つで数字一個分のフォントを使ってるから。
    -- ちなみに、いわゆる「全角スペース」を使ってもいい感じの幅にはならなかった。
    NCHAR(8204) + SPACE((@max_len - LEN(LTRIM(STR(col, 16, 1)))) * 2) + LTRIM(STR(col, 16, 1))
FROM ...;

NCHAR(8204) は、U+200C*1 という (通常) 不可視の文字で、当該アプリケーションで空白文字とみなされなかったため、その後に空白を詰めることで解決しましたとさ。
・・・SQL で見た目にこだわるのが間違ってるんですよという心の声はもちろん胸にしまっておきましたよ。効率?何それ、おいしいの?


# ちなみに、「(通常) 不可視の文字」としてるのは、当然そこに存在するからなわけで・・・
# ためしに Unicode 非対応なサクラエディタにコピペしてみたら、なんか制御文字っぽいものがw
# さらに Excel に貼り付けてみたところ、INT 関数はエラーになるわ、SUM してもエラーになるわ・・・
# もし Excel に貼り付けた後も色々いじくりたいなら、
# INT(RIGHT(cell, LEN(cell) - 1)) して U+200C を取り除いちゃいましょう。

*1:Zero-width non-joiner