Очень легко проверить. Например, 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
.
Вы можете запустить аналогичную проверку для любых других СУБД, которые вы используете. Различные двигатели могут вести себя по-разному, но я ожидаю, что все они будут придерживаться исходного типа столбца. Например, усреднение двух значений int
100
и 101
может привести к 100
или 101
(все еще int
), но никогда 100.5
.
Для SQL Server это поведение documented. Я бы ожидать что-то подобное для всех остальных двигателей:
AVG() вычисляет среднее значение из набора значений путем деления суммы этих значений с помощью подсчета ненулевых значений. Если сумма превышает максимальное значение для типа данных возвращаемого значения, будет возвращена ошибка .
Итак, вы должны быть осторожны при вычислении простого среднего, а не только продукта.
Вот выдержка из SQL 92 Standard:
6) Пусть DT будет тип данных выражения в < значение>.
9) Если SUM или AVG указано, то:
а) DT не должна быть строка символов, строка битов, или даты и времени.
б) Если СУММА задана и ДТ является точным числовым с масштабом S, то типом данных результата является точным числовым с реализацией определяется точности и масштабом S.
с) Если указан AVG и DT является точечным числовым, то тип данных результат точный численный с точностью, определяемой реализацией, а не меньше точности DT и шкалы, определяемой реализацией, а не меньше шкалы DT.
d) Если DT является приблизительным числовым, то тип данных результата равен приблизительный числовой с точностью, определяемой реализацией, не менее , чем точность DT.
e) Если DT является интервалом, то типом данных результата является интервал с той же точностью, что и DT.
Таким образом, СУБД может конвертировать int
для большего типа при расчете AVG
, но он должен быть exact numeric
типа, а не с плавающей точкой. В любом случае, в зависимости от значений, вы все равно можете получить арифметическое переполнение.
Для информации: ваш пример отлично работает в Postgres (и Oracle). –