2013-08-26 6 views
5

私はこのSQLMSSQL - すべての異なる小数精度で労働組合

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と同じように、データが消失しない場所で常に精度を使用するべきではありませんか?

Thx。

答えて

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)) 
0

は通常、クエリがそうでなければ合計を使用して文字列値を渡すか、それが文字列である小数この

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

OR

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

を試してみて、同じ結果のためにこれを試してみてくださいこれは実際のフォーマットです

SELECT sum(convert(decimal,1.4,3)) UNION ALL 
SELECT sum(2.0400) union all 
SELECT sum(1.24) 
0

は、私は、これはかなり古い問題であることを知っているが、既存の答えのどれもが対処するように見えるん

SELECT convert(decimal(18,4),Sum(1.4)) UNION ALL 

SELECT convert(decimal(18,4),Sum(2.0400)) UNION ALL 

SELECT convert(decimal(18,4),Sum(1.24)) 
3

このクエリを試してみてください「なぜ?」あなたの質問への側面。

まず、リテラル式のデータ型は何ですか?私は確認されませんでした(とそれを見ていない)ので、私は次のことを実行しました:

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()オカレンスのために、精度を失うことなくオーバーフローに対応するための最大の可能な領域を与え、クエリが実行される前に最終データ型を決定できることを意味します。

関連する問題