有感于SQL Server 的Sum函数的数据截取问题

本文记录了一位开发者在使用 SQL Server 的 SUM 函数时遇到的数据截取问题,涉及 INT、NUMERIC 和 FLOAT 类型数据。当 NUMERIC 类型数据相加再相除时,结果被截取为小数点后6位,而改为 FLOAT 类型则不会出现此问题。作者提出了可能的 SQL Server 数据处理小 bug,并希望得到专家的解答和分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2009-02-11

今天,在查看测试提交的一个bug问题的时候,发现了一个有关于数据之间相除,和sum函数的关于某类型数据的自动截取问题(也许是我的想当然,呵呵),在这里做一个记录,和大家一起讨论一下。希望哪位牛人可以给予指教!

 

现在自己创建一张数据表,用来测试这个问题:

 

第一步,创建一个表T,创建4个数据类型不同的列,并赋值。

查询结果如下图:

第一步的查询结果集

 

可以发现,此时同样的查询语句和相应的运算规则,在加上sum函数之后,得到的结果是不一样的。a是int,b是numeric,两者sum后相除得到的数据精确度为查询分析器的最大精确度;c和d都是numeric型,这两者sum后相除得到的数据精确度则为小数点后6位。

 

如果对结果加上round函数进行截取的话,得到以下结果:

 

round的测试

 

 

 

可以发现,round函数对于结果截取6位的问题没有影响。

 

 

 

第二步,接着进行其它类型数据的实验

 

 

修改数据类型为decimal后的结果

由结果可见,修改为decmial之后,数据仍然是截取6位。

 

第三步,测试float的类型。

 

结果集

float的测试

可以发现,修改为float类型之后,数据就不再发生截取为精确度为小数点后6位的情况了。

 

 

不解中。

查了下SQL server的帮助,关于sum函数的说明如下:

 

SUM ( [ ALL | DISTINCT ] expression )

参数

ALL

对所有的值应用此聚合函数。ALL 是默认值。

DISTINCT

指定 SUM 返回唯一值的和。

expression

常量、列或函数与算术、位和字符串运算符的任意组合。expression 是精确数字或近似数字数据类型类别(bit 数据类型除外)的表达式。不允许使用聚合函数和子查询。有关详细信息,请参阅表达式(Transact-SQL)

返回类型

以最精确的 expression 数据类型返回所有 expression 值的和。

表达式结果 返回类型

整数类别

int

decimal 类别 (p, s)

decimal(38, s)

money 和 smallmoney 类别

money

float 和 real 类别

float

重要事项:
当使用 CUBE 或 ROLLUP 时,不支持非重复聚合,例如 AVG(DISTINCT column_name)、COUNT(DISTINCT column_name)、MAX(DISTINCT column_name)、MIN(DISTINCT column_name) 和 SUM(DISTINCT column_name)。如果使用这类聚合,SQL Server 2005 Database Engine 将返回错误消息并取消查询。

 

 

 

 

针对这个情况分析,当数据类型都为DECIMAL(20,10)的时候,按照帮助文档的规则的话,经过sum函数处理之后的值应该也是DECIMAL(20,10)。
可实际情况是,当数据类型都为numeric或者DECIMAL类型时,数据在sum函数处理后再相除的话,会发生数据自动截取为小数点后6位的情况。而当数据类型都为float,或一个为int、一个为DECIMAL等数据类型时(还有其他场景,就不一一举例了),此时不会发生小数位的自动截取为6位的情况。
个人初步觉得是SQL server的数据处理的一个小bug所致,希望有高手能够给予帮助和分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值