很容易检查。例如,SQL Server 2008。
DECLARE @T TABLE(i int);
INSERT INTO @T(i) VALUES
(2147483647),
(2147483647);
SELECT AVG(i) FROM @T;
结果
(2 row(s) affected)
Msg 8115, Level 16, State 2, Line 7
Arithmetic overflow error converting expression to data type int.
没有魔法。列类型为int,服务器使用相同类型的内部变量int将值相加,中间结果超出int的范围。
您可以对您使用的任何其他 DBMS 运行类似的检查。不同的引擎可能表现不同,但我希望它们都坚持原来的列类型。例如,平均两个int 值100 和101 可能会导致100 或101(仍然是int),但绝不会导致100.5。
对于 SQL Server,此行为是 documented。我希望所有其他引擎都有类似的东西:
AVG() 通过除以总和来计算一组值的平均值
这些值由非空值的计数。如果总和超过
返回值的数据类型的最大值,错误将是
返回。
因此,在计算简单平均值时也必须小心,而不仅仅是乘积。
这是SQL 92 Standard的摘录:
6) 设DT为的数据类型。
9) 如果指定了 SUM 或 AVG,则:
a) DT 不能是字符串、位串或日期时间。
b) 如果指定了 SUM 并且 DT 是具有刻度 S 的精确数字,则
结果的数据类型是具有实现定义的精确数字
精度和尺度S。
c) 如果指定了 AVG 并且 DT 是精确数字,那么数据类型
结果是精确的数字,具有实现定义的精度不是
小于 DT 的精度和实现定义的比例不
小于DT的规模。
d) 如果 DT 是近似数值,那么结果的数据类型是
具有实现定义的精度不少于的近似数值
比DT的精度。
e) 如果 DT 为区间,则结果的数据类型为区间
与 DT 具有相同的精度。
所以,DBMS 在计算AVG 时可以将int 转换为更大的类型,但它必须是exact numeric 类型,而不是浮点型。在任何情况下,根据值,您仍然可以得到算术溢出。