转换为float vs int返回不同的结果

时间:2012-11-01 15:41:08

标签: sql sql-server tsql

在数学上,这些结果是相似的,我只是对他们的行为感到好奇。第一个版本,当我的局部变量声明为浮点数时,舍入函数停止显示在第二个小数点的小数。在第二个版本中,局部变量声明为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

1 个答案:

答案 0 :(得分:1)

首先,让我们看一下ROUND()函数定义:

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

它表示ROUNDED到指定的长度,而不是TRUNCATED到指定的长度。

现在,使用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函数在传递一个float时返回一个浮点数,在传递一个数字时返回一个小数。

您可以在那里阅读所有相关内容:http://msdn.microsoft.com/en-us/library/ms175003.aspx

最后,您可以看到当零开始时浮点数被截断,并且数字永远不会被截断,直到它达到比例限制:

select CONVERT(float, 3.330000),          -- 3.33
       CONVERT(numeric(17, 12), 3.330000) -- 3.330000000000