SQL Server: SUM приводит к арифметическому переполнению без фактического превышения предела INT - PullRequest
0 голосов
/ 07 сентября 2018

У меня следующий запрос SQL:

SELECT SomeId, COUNT(*) AS Entries, SUM(Field1) AS MySum
FROM MyTable
WHERE SomeId IN (......~400 items......)
GROUP BY SomeId

И он выдает эту ошибку:

Сообщение 8115, Уровень 16, Состояние 2, Строка 1
Ошибка арифметического переполненияпреобразование выражения в тип данных int.

Field1 равно INT.Я знаю, что максимальное значение INT равно 2147483647. Но проблема в том, что сумма всех значений Field1 не близка к максимальному значению INT.Максимальное значение Field1 равно 156, максимальное значение отдельной группы равно 600, а сумма всех сумм в наборе результатов равна всего 14660.

Если я произнесу Field1 как BIGINT, это сработает,но я не думаю, что это правильное решение.

Я обнаружил, что этот запрос работает, только если я уменьшу количество идентификаторов в предложении WHERE IN.И это никак не связано с конкретными «проблемными» идентификаторами.Если я оставляю только первую половину идентификаторов, это работает, если я оставляю вторую половину, это тоже работает, но они почему-то не работают вместе.Любые предложения?

ОБНОВЛЕНИЕ

Я нашел другой обходной путь, который также может быть реализован с EF Core.Соединение можно использовать вместо WHERE IN:

INNER JOIN (SELECT * FROM SomeIdTable WHERE Id IN (...)) AS x ON x.Id = SomeId

Интересно, что план выполнения говорит, что он стоит 49% по сравнению с исходным запросом WHERE IN.

Это просто обходной путьи это не решает проблему случайного «арифметического переполнения», вызванного WHERE IN со слишком большим количеством значений.

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Попробуйте преобразовать в bigint только в запросе, а не в таблице def.

SELECT SomeId, COUNT(*) AS Entries, SUM(convert(bigint, Field1)) AS MySum
FROM MyTable
WHERE SomeId IN (......~400 items......)
GROUP BY SomeId
0 голосов
/ 07 сентября 2018

Если ваши ~ 400 элементов последовательны, вы можете попробовать использовать команду between, например:

SELECT SomeId, COUNT(*) AS Entries, SUM(Field1) AS MySum
FROM MyTable
WHERE SomeId BETWEEN 'FIRST_VALUE' AND 'SECOND_VALUE'
GROUP BY SomeId
...