Как рассчитать интервал между двумя столбцами datetime2 (SQL Server)?
Привет я пытаюсь вычислить разницу между двумя столбцами типа datetime2.
Однако SQL Server (2012), похоже, не нравится следующее:
select cast ('2001-01-05 12:35:15.56786' as datetime2)
- cast ('2001-01-01 23:45:21.12347' as datetime2);
Msg 8117, Level 16, State 1, Line 2
Operand data type datetime2 is invalid for subtract operator.
Теперь это работает, если я приведу его к типу datetime:
select cast (cast ('2001-01-05 12:35:15.56786' as datetime2) as datetime)
- cast (cast ('2001-01-01 23:45:21.12348' as datetime2) as datetime);
1900-01-04 12:49:54.443
Тем не менее, я теряю точность при приведении его к дате и времени (обратите внимание на 3-значную десятичную точность выше). В этом случае мне действительно нужны все 5 десятичных знаков. Есть ли способ получить интервал между двумя столбцами datetime2 и при этом сохранить точность до 5 десятичных знаков? Благодарю.
2 ответа
Вы можете просто использовать DateDiff
Возвращает количество (целое число со знаком) указанных границ даты, пересеченных между указанной начальной датой и конечной датой.
select DATEDIFF(MILLISECOND, cast('20010101 23:45:21.12347' as datetime2),
cast('20010105 12:35:15.56786' as datetime2))
К сожалению, пытаясь получить требуемую точность с этим:
select DATEDIFF(MICROSECOND, cast('20010101 23:45:21.12347' as datetime2),
cast('20010105 12:35:15.56786' as datetime2))
приводит к ошибке переполнения:
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.
Одним из способов достижения требуемой точности было бы итеративное разбиение на гранулированные компоненты времени (дни, часы, минуты, секунды и т. Д.) И вычитание этого значения из значений с помощью DateAdd(), например
remainingAtLowerGranularity = DateAdd(granularity, -1 * numFoundInStep, value)
Чтобы найти разницу между двумя датами, вам нужно использовать функцию DATEDIFF
select DATEDIFF(millisecond,'20010105 12:35:15.56786','20010101 23:45:21.12347')
Через 5 лет это вряд ли поможет славоо, но этот многословный пример, вероятно, делает то, о чем просили:
@FromDateTime DATETIME2 = CAST('20010101 23:45:21.12347' AS DATETIME2),
@ToDateTime DATETIME2 = CAST('20010105 12:35:15.56786' AS DATETIME2),
@FromMicroSecs NUMERIC,
@FromDateTimeNoMicroSecs DATETIME,
@ToMicroSecs NUMERIC,
@ToDateTimeNoMicroSecs DATETIME;
SELECT
@FromMicroSecs = DATEPART(MICROSECOND, @FromDateTime),
@FromDateTimeNoMicroSecs = CAST(DATEADD(MICROSECOND, -1 * @FromMicroSecs, @FromDateTime) AS DATETIME),
@ToMicroSecs = DATEPART(MICROSECOND, @ToDateTime),
@ToDateTimeNoMicroSecs = CAST(DATEADD(MICROSECOND, -1 * @ToMicroSecs, @ToDateTime) AS DATETIME);
SELECT
CAST(DATEDIFF(SECOND, @FromDateTimeNoMicroSecs, @ToDateTimeNoMicroSecs) AS NUMERIC) * 1000000 + @ToMicroSecs - @FromMicroSecs AS AnswerInMicroseconds;```