SQL Server の有効桁数に関して気が向いたので理解を深めてみました。
例えばですが、decimal(10,0)
で格納されている金額フィールド(単位は円)を
クエリ上で単位を千円に変える場合
SELECT
Kingaku / 1000 AS KingakuInThousands
みたいな感じになるかと思いますが、この KingakuInThousands
の有効桁数はいくつで、小数桁数はいくつでしょう?
これは計算式が決まっていて、下記のリンクに有る表にしたがって決定されます。
MSDN:有効桁数、小数点以下桁数、および長さ (Transact-SQL)
今回は除算ですので 「$e1 / e2$」 の行を見ます。
なお、今回の式の場合は
$e1$ … Kingaku
$e2$ … 1000
$p1$ … Kingaku
の有効桁数 : 10 (deciaml(10, 0)
なので)
$p2$ … 1000 の有効桁数 :4
$s1$ … Kingaku
の小数桁数 : 0 (deciaml(10, 0)
なので)
$s2$ … 1000 (int
) の小数桁数 : 0
有効桁数は $p1 - s1 + s2 + \max(6, s1 + p2 + 1)$ の式より、
\begin{aligned}
& 10 - 0 + 0 + \max(6, 0 + 4 + 1)\\
= & 10 + \max(6,\ 5)\\
= & 10 + 6\\
= & 16
\end{aligned}
小数桁数は $\max(6, s1 + p2 + 1)$ の式より
\begin{aligned}
& \max(6,\ 0 + 4 + 1)\\
= & \max(6,\ 5)\\
= & 6
\end{aligned}
となるので、KingakuInThousands
は 有効桁数 16、小数桁数 6 となります。
つまり、decimal(16, 6)
になっている…(ハズ…)
int
による割り算を挟むと小数桁数が 6 桁になっちゃうのは、このせいなのですねー
なお、割る数の int
を 6 桁 (100000
) にすると、上記の式より、小数桁数が 7 桁になりました。
理屈がわかると色々と納得できたりしますね。