このクエリを試してみてください「なぜ?」あなたの質問への側面。
まず、リテラル式のデータ型は何ですか?私は確認されませんでした(とそれを見ていない)ので、私は次のことを実行しました:
select 1.4 union all
select 'frob'
エラーを返した:
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to numeric.
わかりましたので、1.4
およびその他のリテラルはnumeric
あります - 別名decimal
。
次に、decimal(p,s)
を渡された場合、SUM
関数の戻り値の型のものです:
decimal(38, s)
わかりましたので、あなたのクエリで3つのSUM
式のデータ型はdecimal(38,1)
あり、decimal(38,4)
とdecimal(38,2)
。選択できる3つのデータ型が与えられた場合、differing precisions and scalesの規則に基づいて、decimal(38,1)
が最終的に選択された型です。
The result precision and scale have an absolute maximum of 38. When a result precision is greater than 38, the corresponding scale is reduced to prevent the integral part of a result from being truncated.
だから、最終的には、バックdecimal
上のドキュメントへ:
By default, SQL Server uses rounding when converting a number to a decimal or numeric value with a lower precision and scale. However, if the SET ARITHABORT option is ON, SQL Server raises an error when overflow occurs. Loss of only precision and scale is not sufficient to raise an error.
だから、あなたの最終的な結果です。まず
あなたは一般的に、sum
は、複数の行に対して動作することを実現し、それが自分自身のデータ型をオーバーフローして与えられた精度とスケールの複数の値のために容易に可能になるまで、このタイプは、意外に思えるかもしれません。 decimal(38,s)
は、特にSUM()
オカレンスのために、精度を失うことなくオーバーフローに対応するための最大の可能な領域を与え、クエリが実行される前に最終データ型を決定できることを意味します。