2016-12-09 9 views
-2

以下のSQL問合せでは、異なる結果が返されます。 精度は、元のクエリとケース3のコメントなしで異なります。 理由は何ですか?私は2014年SQL - 小数点以下を切り捨てる場合

declare @d1 decimal(20, 15), @d2 decimal(20, 15), @d3 decimal(20, 15), @d4 decimal(20, 15) 
set @d1 = 22.0 
set @d2 = 22.0 
set @d3 = 1.00000 
set @d4 = 7.0 

select 
    case when (1 > 0) then @d1/@d4 
     when (2 > 0) then @d2/@d4 
     when (3 > 0) then @d2/(@d4 * @d3) 
    end 


--Results: 
--Without case 3 commented: 3.142857 
--With case 3 commented: 3.142857142857142857 
+0

は、floatを使用してみてください。 –

+2

@KeithJohnHutchison:浮動小数点は正確ではありません。 – Pred

+1

@KeithJohnHutchison質問は*なぜこれが起こるのですか?そしてbtw:FLOATは - ほとんどの場合 - 何かが避けなければならないもの... – Shnugo

答えて

4

CASE表現は、特定のデータ型で結果を生成するために持っているのSQL Serverを実行しています。そのデータ型は、CASE式がコンパイルされたときに決定され、すべてのTHEN節のデータ型とELSE節から派生します。

case 3式のデータ型は他の式のデータ型よりも小さいため、その式が含まれていてすべての式が考慮されると結果がより限定されます。

WHEN式のそれぞれのデータタイプを決定するための正確なルールは、Precision, Scale and Lengthのマニュアルに記載されています。

2

これが期待される動作であり、CASE-WHEN構築物で行うには(ほとんど)何もしています:https://msdn.microsoft.com/en-us/library/ms190476.aspx

オペランド式は精度で、精密P1とスケールS1、及び発現E2と、表現E1と表記されていますp2および縮尺s2。 10進ではない式の精度と位取りは、式のデータ型に対して定義された精度と位取りです。

*結果精度とスケールの絶対最大値は38です。結果精度が38より大きい場合、結果の整数部分が切り捨てられないように、対応する縮尺が縮小されます。

Operation  Result precision      Result scale * 
e1 + e2   max(s1, s2) + max(p1-s1, p2-s2) + 1 max(s1, s2) 
e1 - e2   max(s1, s2) + max(p1-s1, p2-s2) + 1 max(s1, s2) 
e1 * e2   p1 + p2 + 1       s1 + s2 
e1/e2   p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1) 
e1 UNION ** e2 max(s1, s2) + max(p1-s1, p2-s2)  max(s1, s2) 
e1 % e2   min(p1-s1, p2 -s2) + max(s1,s2) max(s1, s2) 

** e1 { UNION | EXCEPT | INTERSECT } e2

0

あなたはラウンドfuncrionを使用することができます。

select round(case when (1 > 0) then @d1/@d4 
    when (2 > 0) then @d2/@d4 
    when (3 > 0) then @d2/(@d4 * @d3) 
end,5) 
関連する問題