2009-02-11
今天,在查看测试提交的一个bug问题的时候,发现了一个有关于数据之间相除,和sum函数的关于某类型数据的自动截取问题(也许是我的想当然,呵呵),在这里做一个记录,和大家一起讨论一下。希望哪位牛人可以给予指教!
现在自己创建一张数据表,用来测试这个问题:
第一步,创建一个表T,创建4个数据类型不同的列,并赋值。
查询结果如下图:
可以发现,此时同样的查询语句和相应的运算规则,在加上sum函数之后,得到的结果是不一样的。a是int,b是numeric,两者sum后相除得到的数据精确度为查询分析器的最大精确度;c和d都是numeric型,这两者sum后相除得到的数据精确度则为小数点后6位。
如果对结果加上round函数进行截取的话,得到以下结果:
可以发现,round函数对于结果截取6位的问题没有影响。
第二步,接着进行其它类型数据的实验
由结果可见,修改为decmial之后,数据仍然是截取6位。
第三步,测试float的类型。
结果集
可以发现,修改为float类型之后,数据就不再发生截取为精确度为小数点后6位的情况了。
不解中。
查了下SQL server的帮助,关于sum函数的说明如下:
SUM ( [ ALL | DISTINCT ] expression ) |
参数
-
对所有的值应用此聚合函数。ALL 是默认值。
ALL
-
指定 SUM 返回唯一值的和。
DISTINCT
-
常量、列或函数与算术、位和字符串运算符的任意组合。expression 是精确数字或近似数字数据类型类别(bit 数据类型除外)的表达式。不允许使用聚合函数和子查询。有关详细信息,请参阅表达式(Transact-SQL)。
expression
返回类型
以最精确的 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所致,希望有高手能够给予帮助和分析。