Как рассчитать интервал между двумя столбцами 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;```
Другие вопросы по тегам