1

从数学上讲,这些结果是相似的,我只是对它们的行为感到好奇。当我的局部变量被声明为浮点数的第一个版本时,舍入函数会停止显示在第二个小数处的小数。在将局部变量声明为 int 的第二个版本中,round函数四舍五入到小数点后两位,然后添加一堆零。为什么变量类型会导致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

--不四舍五入到小数点后两位

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.

它说 ROUNDED 到指定的长度,而不是 TRUNCATE 到指定的长度。

现在,使用 int 和 float 会产生完全不同的表达式类型。您可以轻松地将它们与以下查询进行比较(我切换COUNT(*)到 1,@totalpop也切换到 1):

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,表达式会给你一个数字。使用浮点数,你会得到一个浮点数。根据微软的说法,他们的 ROUND 函数在传递一个浮点数时将返回一个浮点数,当传递一个数字时返回一个小数。

您可以在那里阅读所有相关信息: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 回答