Функция DATEDIFF привела к переполнению в SQL Server 2016

У меня есть таблица в SQL Server 2016 со следующими данными:

id | t | memory -------+-------------------------+------------ 620255 | 2017-07-17 16:11:25.100 | 11632640 620127 | 2017-07-17 16:11:24.100 | 11632640 619999 | 2017-07-17 16:11:23.097 | 11632640 619872 | 2017-07-17 16:11:22.097 | 11632640 

Я пытаюсь получить среднее значение memory в секунду. Поэтому, чтобы сделать это, я попробовал следующий запрос:

 SELECT AVG(memory) AS avgMemory, DATEADD(second, DATEDIFF(second, 0, t), 0) AS t FROM Table1 AS Table1 WHERE t BETWEEN '2017-07-17 16:11:00.000' AND '2017-07-17 16:12:00.000' GROUP BY DATEADD(second, DATEDIFF(second, 0, t), 0) ORDER BY t ASC; 

Но после выполнения я получаю следующую ошибку:

Датированная функция привела к переполнению. Количество дат, разделяющих два экземпляра даты / времени, слишком велико. Попробуйте использовать датифф с менее точной датой.

Согласно официальным документам и этой должности , максимальная разница в секундах может составлять 68 лет, но в моем случае это всего лишь 60 секунд.

Так почему я получаю эту ошибку? И что я могу сделать, чтобы решить эту проблему?

Вот SQLFiddle с указанной проблемой: Fiddle

Проблема здесь – «дата начала».

В select DATEDIFF(second, 0, t) 0 означает 1900-01-01, что слишком далеко от 2017, поэтому время в секундах, прошедшее с 1900-01-01 до 2017-07-17, переполняет простое целое число, это не просто " 60 секунд "

Вы также можете использовать другую дату (например, 2017-07-17 00:00:00.000 ) в качестве контрольной точки для своих расчетов:

 SELECT AVG(memory) AS memory, DATEADD(second, DATEDIFF(second, '2017-07-17 00:00:00.000', t), '2017-07-17 00:00:00.000') AS t FROM Table1 AS Table1 WHERE t BETWEEN '2017-07-17 16:11:00.000' AND '2017-07-17 16:12:00.000' GROUP BY DATEADD(second, DATEDIFF(second, '2017-07-17 00:00:00.000', t), '2017-07-17 00:00:00.000') ORDER BY t ASC; 

SQL Fiddle

Для этой цели SQL Server предлагает datediff_big() :

 SELECT AVG(memory) AS avgMemory, DATEADD(second, DATEDIFF_BIG(second, 0, t), 0) AS t FROM Table1 AS Table1 WHERE t BETWEEN '2017-07-17 16:11:00.000' AND '2017-07-17 16:12:00.000' GROUP BY DATEADD(second, DATEDIFF_BIG(second, 0, t), 0) ORDER BY t ASC; 

Вы также можете сделать это, преобразовая значение в строку:

 SELECT AVG(memory) AS avgMemory, CONVERT(VARCHAR(19), t, 120) as t FROM Table1 AS Table1 WHERE t BETWEEN '2017-07-17 16:11:00.000' AND '2017-07-17 16:12:00.000' GROUP BY CONVERT(VARCHAR(19), t, 120) ORDER BY t ASC; 

Эта версия работает во всех поддерживаемых версиях SQL Server.

  • Использование SQLBulkCopy - Значительно большие таблицы в SQL Server 2016, чем в SQL Server 2014
  • Динамическая строка запроса SQL усечена до 256 символов
  • Невозможно импортировать SQL Azure bacpac в 2016 CTP
  • Буферный пул в SQL Server FileStream
  • Прием данных Microsoft R слишком медленный
  • SQL Server 2016 - всегда зашифрован - отсутствует способ генерации PowerShell
  • OPENJSON не работает в SQL Server?
  • MS SQL без предупреждения при вставке столбца DateTime в Date
  • Понимание определенного типа тупика
  • Передача данных SSIS с Azure SQL на локальный SQL Server 2016
  • Как выбрать все значения параметров в SSRS?
  • Давайте будем гением компьютера.