Ошибка арифметического переполнения при усреднении / суммировании миллисекунд - PullRequest
0 голосов
/ 05 сентября 2018

У меня много проблем с решением этой проблемы (я просматривал другие посты с той же проблемой, но, к сожалению, мне не очень повезло с применением предложенных решений к моей ситуации).

У меня есть одна (очень большая) таблица с транзакционной информацией. Одним из столбцов является Время выполнения транзакции (тип поля Время). Время выполнения обычно <1 сек, но оно может доходить до пары минут. </p>

Ежедневные, еженедельные, ежемесячные и годовые отчеты о транзакциях должны быть доступны, и они должны содержать среднее время транзакции. Из-за большого количества записей я сталкиваюсь с переполнением при выполнении среднего / суммы.

Вот (упрощенный) пример, который я использую для тестирования:

SELECT  
DATEPART (YEAR, TimeStamp) as 'Year',
COUNT(*) as 'Transaction count',
AVG((DATEDIFF(MILLISECOND, '0:00:00',ExecutionTime))) as 'Average execution time',
SUM((DATEDIFF(MILLISECOND, '0:00:00',ExecutionTime))) as 'Total execution time'
FROM RecordedTransactions
GROUP BY 
DATEPART (YEAR, TimeStamp)

Как лучше всего решить проблему переполнения?

Ответы [ 2 ]

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

Вместо этого попробуйте убедиться, что все ваши типы данных обрабатываются как BIGINT, а не int:

SELECT DATEPART(YEAR, TimeStamp) AS Year,
       COUNT_BIG(*) AS [Transaction count],
       AVG((DATEDIFF_BIG(MILLISECOND, '0:00:00', ExecutionTime))) AS [Average execution time],
       SUM((DATEDIFF_BIG(MILLISECOND, '0:00:00', ExecutionTime))) AS [Total execution time]
FROM RecordedTransactions
GROUP BY DATEPART(YEAR, TimeStamp);

SUM и AVG возвращают тот же тип данных, который они были переданы. COUNT возвращает int, а COUNT_BIG возвращает bigint. Для SUM это означает, что (в соответствии с вашим запросом), если он превысит 2 147 483 647, он потерпит неудачу. Использование DATEDIFF_BIG означает, что возвращаемое значение равно bigint, поэтому ваш SUM может вернуть значение до 9,223,372,036,854,775,807.

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

Вам нужно использовать DATEDIFF_BIG вместо DATEDIFF:

DATEDIFF_BIG (datepart, startdate, enddate)

Эта функция возвращает количество (как большое целое число со знаком значение) указанных границ даты, пересеченных между указанной начальной датой и конечной датой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...