5

このSQLを実行すると

SELECT 1.4 UNION ALL
SELECT 2.0400 union all
SELECT 1.24

次の結果が得られます。

1.4000
2.0400
1.2400

しかし、次のSQLを実行すると

SELECT sum(1.4) UNION ALL
SELECT sum(2.0400) union all
SELECT sum(1.24)

次の結果が得られます:

1.4
2.0
1.2

すべてのレコードに適用される精度 (スケール) に違いがあるのはなぜですか? 最初のSQLのように、データが失われない精度を常に使用すべきではありませんか?

どうも。

4

5 に答える 5

3

これはかなり古い質問であることは知っていますが、既存の回答はどれも「なぜ?」に対処していないようです。あなたの質問への側面。

まず、リテラル式のデータ型は何ですか? よくわからなかった(そして調べなかった)ので、次を実行しました:

select 1.4 union all
select 'frob'

エラーを返します:

メッセージ 8114、レベル 16、状態 5、行 1
データ型 varchar から数値への変換エラー。

さて、1.4その他のリテラルはnumeric- akadecimalです。

次に、 1SUMが渡された場合の関数の戻り値の型は次のとおりです。decimal(p,s)

10 進数 (38、秒)

SUMわかりました。クエリの 3 つの式のデータ型はdecimal(38,1)decimal(38,4)およびdecimal(38,2)です。これら 3 つのデータ型から選択できる場合、異なる精度とスケールdecimal(38,1)のルールに基づいて、 が最終的に選択される型になります。

結果の精度と位取りの絶対最大値は 38 です。結果の精度が 38 を超える場合、結果の整数部分が切り捨てられないように、対応する位取りが縮小されます。

最後に、次のドキュメントに戻りますdecimal

既定では、SQL Server は数値を 10 進数または数値に変換するときに、精度とスケールが低い場合に丸めを使用します。ただし、SET ARITHABORT オプションが ON の場合、SQL Server はオーバーフローが発生したときにエラーを発生させます。精度と位取りが失われるだけでは、エラーが発生するのに十分ではありません。

それがあなたの最終結果です。


1最初は、この型は驚くべきものに思えるかもしれませんが、一般にsumが複数の行に対して動作し、特定の精度とスケールの複数の値が独自のデータ型をオーバーフローする可能性が容易にあることに気付くまでは。特定decimal(38,s)のオカレンスに対して、精度を失うことなくオーバーフローに対応できる最大のスペースを提供し、クエリが実行される前に最終的なデータ型を決定できることを意味します。 SUM()

于 2013-11-25T11:40:08.373 に答える
0

これを試して同じ結果を得る、

SELECT Cast(Sum(1.4) As Numeric(18,4)) UNION ALL
SELECT Cast(Sum(2.0400) As Numeric(18,4)) union all
SELECT Cast(Sum(1.24) As Numeric(18,4))
于 2013-08-26T10:06:46.040 に答える
0

これを試して

SELECT sum(1.4)/1.0 UNION ALL
SELECT sum(2.0400)/1.0 union all
SELECT sum(1.24)/1.0

また

SELECT sum(1.4)/1.0 UNION ALL
SELECT sum(2.0400) union all
SELECT sum(1.24)
于 2013-08-26T10:08:17.983 に答える
0

通常のクエリは文字列値を渡します。それ以外の場合は sum または decimal を使用します。指定された形式に変換される文字列です。これは事実です。

SELECT sum(convert(decimal,1.4,3)) UNION ALL
SELECT sum(2.0400) union all
SELECT sum(1.24)
于 2013-08-26T10:08:21.443 に答える