Показаны сообщения с ярлыком SQL. Показать все сообщения
Показаны сообщения с ярлыком SQL. Показать все сообщения

25 августа 2017 г.

MSSQL DATETIME2, DATETIME truncate минуты, секунд.

В какой то момент может понадобится  возможность в SQL запросе по полю типа DATETIME или DATETIME2 производить сравнение дат с какой то конкретной датой, отбросив при этом минуты, секунды, миллисекунды. Для дат, которые лежат в настоящие годы, это можно сделать без каких либо проблем через DATEADD и DATEDIFF. Пример использования с обрезанием до минут:

SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, '2017-08-25 00:00'), 0)

В случае, если требуется обрезание до секунд, миллисекунд или любой другой составляющей даты достаточно поменять первый параметр метода DATEADD и DATEDIFF на нужный тип. Список типов одинаков и описан на msdn каждого метода.

Все было бы хорошо, но есть ложка дёгтя в бочке с медом. DATEDIFF возвращает количество прошедших минут, секунд, миллисекунд с 1900-01-01 00:00:00 при этом возвращаемое значение INT. Это значит:
  • Даты до 1900 года будут иметь отрицательное значение
  • Мы имеем ограничение на возвращаемое значение, равное диапазону значений INT, а это ровняется от -2,147,483,648 до +2,147,483,647.
  • Чем меньшую единицу измерения времени мы хотим обрезать, тем ближе к 1900 году должна быть дата в таблице.
При этом, максимальный год для DATETIME и DATETIME2 это 9999. И если в таблице будет присутствовать значение, которая будет приводить к переполнению INT при вычисление DATEDIFF - вы будете получать ошибку на ваш SQL запрос:
The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.