Как рассчитать интервал между двумя столбцами datetime2 (SQL Server)?

Привет, я пытаюсь вычислить разницу между двумя столбцами типа datetime2.

Однако SQL-серверу (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.

Теперь это работает, если я приведу его к типу даты и времени:

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 знаков после запятой? Спасибо.


person Kevin Tianyu Xu    schedule 14.10.2013    source источник


Ответы (3)


Вы можете просто использовать 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)
person Mitch Wheat    schedule 14.10.2013
comment
Это вычисление интервала между двумя научными показателями. Сохраните значение интервала, а затем добавьте его к другому datetime2, чтобы делать прогнозы. Хотя разрыв между двумя датами обычно не такой большой (4 дня в приведенном выше примере). Может быть, это немного более реалистично. выберите DATEDIFF(MICROSECOND, cast('20010101 23:45:21.12347' as datetime2), cast('20010102 00:05:15.56786' as datetime2)) - person Kevin Tianyu Xu; 14.10.2013
comment
Кажется, это работает для достаточно малых интервалов. Может быть, просто помните, что для такой точности существует верхний предел в микросекундах? Если бы только SQL-сервер datetime2 вел себя аналогично datetime в этом отношении, мне не пришлось бы сталкиваться с такими проблемами. - person Kevin Tianyu Xu; 14.10.2013

Чтобы найти разницу между двумя датами, вам нужно использовать функцию DATEDIFF

select DATEDIFF(millisecond,'20010105 12:35:15.56786','20010101 23:45:21.12347') 
person Igor Borisenko    schedule 14.10.2013

Через 5 лет это вряд ли поможет slavoo, но этот многословный пример, вероятно, делает то, о чем просили:

    @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;```
person articus    schedule 05.08.2019