1

数学的には、これらの結果は似ています。私はそれらの動作に興味があります。ローカル変数がfloatとして宣言されている最初のバージョンでは、丸め関数は小数点以下2桁目に表示される小数点を停止します。ローカル変数がintとして宣言されている2番目のバージョンでは、round関数は小数点以下2桁に丸めてから、ゼロの束を追加します。変数タイプによってround関数の動作が異なるのはなぜですか?

declare @totalpop float 
set @totalpop = (select count(distinct patid) from members)
select @totalpop
select edutext
,COUNT(*) as educationCounts
,round(100.0*COUNT(*)/@totalpop,2)
from
(
select distinct m.patid, e.eduText
    from members as m
    inner join EducationTable as e on e.eduID = m.education
)x
group by x.eduText

-小数点以下第2位は四捨五入されません

declare @totalpop int
set @totalpop = (select count(distinct patid) from members)
select @totalpop
select edutext
,COUNT(*) as educationCounts
,round(100.0*COUNT(*)/@totalpop,2)
from
(
select distinct m.patid, e.eduText
    from members as m
    inner join EducationTable as e on e.eduID = m.education
)x
group by x.eduText
4

1 に答える 1

1

まず、ROUND()関数の定義を見てみましょう。

Returns a numeric value, rounded to the specified length or precision.

指定された長さに切り捨てられたのではなく、指定された長さに丸められたと表示されます。

現在、intとfloatを使用すると、まったく異なる式タイプが生成されます。次のクエリで簡単に比較できます(私は1に切り替えCOUNT(*)、1にも切り替えました@totalpop):

Select sql_variant_property(100.0 * 1 / convert(int, 1), 'BaseType') BaseType,
       sql_variant_property(100.0 * 1 / convert(int, 1), 'Precision') Precision,
       sql_variant_property(100.0 * 1 / convert(int, 1), 'Scale') Scale

Select sql_variant_property(100.0 * 1 / convert(float, 1.0), 'BaseType') BaseType,
       sql_variant_property(100.0 * 1 / convert(float, 1.0), 'Precision') Precision,
       sql_variant_property(100.0 * 1 / convert(float, 1.0), 'Scale') Scale

これは、intを使用すると、式が数値を与えることを示しています。フロートを使用すると、フロートが得られます。Microsoftによると、ROUND関数は、floatが渡されるとfloatを返し、数値が渡されると10進数を返します。

あなたはそこでそれについてすべて読むことができます:http://msdn.microsoft.com/en-us/library/ms175003.aspx

最後に、ゼロが開始するとフロートが切り捨てられ、スケール制限に達するまで数値が切り捨てられないことがわかります。

select CONVERT(float, 3.330000),          -- 3.33
       CONVERT(numeric(17, 12), 3.330000) -- 3.330000000000
于 2012-11-01T16:50:44.177 に答える