Поделиться через


DATEDIFF (Transact-SQL)

Возвращает количество (целое число со знаком) указанных границ datepart, пересеченных между startdate и enddate.

Обзор всех типов данных и функций даты и времени в языке Transact-SQL см. в разделе Функции даты и времени (Transact-SQL). Сведения и примеры, относящиеся к типам данным и функциям даты и времени, см. в разделе Использование данных даты и времени.

Значок ссылки на разделСинтаксические обозначения в Transact-SQL

Синтаксис

DATEDIFF ( datepart , startdate , enddate )

Аргументы

  • datepart
    Часть аргументов startdate и enddate, которая задает тип пересекаемых границ. В следующей таблице перечислены все допустимые аргументы datepart. Эквивалентные переменные, определяемые пользователем, являются недопустимыми.

    datepart

    Сокращения

    year

    yy, yyyy

    quarter

    qq, q

    month

    mm, m

    dayofyear

    dy, y

    day

    dd, d

    week

    wk, ww

    hour

    hh

    minute

    mi, n

    second

    ss, s

    millisecond

    ms

    microsecond

    mcs

    nanosecond

    ns

  • startdate
    Выражение, которое может быть приведено к значению типа time, date, smalldatetime, datetime, datetime2 или datetimeoffset. Аргумент date может быть выражением, выражением столбца, определяемой пользователем переменной или строковым литералом. Значение startdate вычитается из значения enddate.

    Во избежание неоднозначности используйте четырехзначную запись года. Сведения об обозначении года двумя цифрами см. в разделе Параметр two digit year cutoff.

  • enddate
    См. раздел startdate.

Тип возвращаемых данных

int

Возвращаемое значение

  • Каждое выражение datepart и его краткие формы возвращают одно и то же значение.

Если возвращенное значение выходит за границы диапазона значений типа int (от -2 147 483 648 до +2 147 483 647), возвращается ошибка. Для единицы измерения millisecond максимальная разница между значениями startdate и enddate составляет 24 дня, 20 часов, 31 минута и 23,647 секунды. Для единицы измерения second максимальная разница составляет 68 лет.

Если обоим аргументам startdate и enddate присвоено только значение времени, а аргумент datepart не содержит значения времени, то возвращается значение 0.

При вычислении возвращаемого значения смещение часовых поясов для аргументов startdate и endate не учитывается.

Так как значение типа smalldatetime имеет точность до минуты, то при использовании в аргументах startdate и enddate значения типа smalldatetime секунды и миллисекунды всегда равны 0.

Если переменной типа данных date присвоено только значение времени, в качестве недостающей части даты используется значение по умолчанию: 1900-01-01. Если переменой типа данных time или date присвоено только значение времени, в качестве недостающей части времени используется значение по умолчанию: 00:00:00. Если в одном из аргументов startdate и enddate указано только время, а в другом только дата, в качестве недостающей информации используются значения по умолчанию.

Если аргументы startdate и enddate имеют разные типы данных даты, но при этом один из них имеет больше частей времени или обладает более высокой точностью, значениям недостающих частей другого аргумента присваиваются значения 0.

Границы, указываемые аргументом datepart

Следующие инструкции имеют одинаковые значения аргументов startdate и endate. Указанные даты являются соседними, а временная разница между ними составляет 0,0000001 секунды. Разница между аргументами startdate и endate в каждой инструкции пересекает одну календарную или временную границу аргумента datepart. Каждое выражение возвращает значение 1. Если в данном примере в аргументах startdate и endate указаны различные года и при этом указанные границы находятся в пределах одной календарной недели, то для значения week будет возвращено значение 0.

SELECT DATEDIFF(year, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(quarter, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(month, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(dayofyear, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(day, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(week, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(hour, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(minute, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(second, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(millisecond, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

Замечания

Функция DATEDIFF может использоваться в предложениях WHERE, HAVING, GROUP BY и ORDER BY, а также при составлении списка выбора.

Начиная с SQL Server 2008, DATEDIFF неявным образом приводит строковые литералы к типу datetime2. Это означает, что DATEDIFF больше не поддерживает формат «ГДМ», где дата передается в качестве строки. Необходимо явно привести строку в тип datetime или smalldatetime для использования формата «гдм».

Примеры

В следующих примерах выражения различного типа используются в качестве аргументов для параметров startdate и enddate.

А. Указание столбцов в качестве начальной и конечной даты

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

CREATE TABLE dbo.Duration
    (
    startDate datetime2
    ,endDate datetime2
    )
INSERT INTO dbo.Duration(startDate,endDate)
    VALUES('2007-05-06 12:10:09','2007-05-07 12:10:09')
SELECT DATEDIFF(day,startDate,endDate) AS 'Duration'
FROM dbo.Duration;
-- Returns: 1

Б. Указание определенных пользователем переменных в качестве начальной и конечной даты

В следующем примере в качестве аргументов startdate и enddate выступают определенные пользователем переменные.

DECLARE @startdate datetime2 = '2007-05-05 12:10:09.3312722';
DECLARE @enddate datetime2 = '2007-05-04 12:10:09.3312722'; 
SELECT DATEDIFF(day, @startdate, @enddate);

В. Указание скалярных системных функций в качестве начальной и конечной даты

В следующем примере в качестве аргументов startdate и enddate используются скалярные системные функции.

SELECT DATEDIFF(millisecond, GETDATE(), SYSDATETIME());

Г. Указание скалярных вложенных запросов и скалярных функций в качестве начальной и конечной даты

В следующем примере в качестве аргументов startdate и enddate используются скалярные вложенные запросы и скалярные функции.

USE AdventureWorks2008R2;
GO
SELECT DATEDIFF(day,(SELECT MIN(OrderDate) FROM Sales.SalesOrderHeader),
    (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader));

Д. Указание констант в качестве начальной и конечной даты

В следующем примере в качестве аргументов startdate и enddate используются символьные константы.

SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635'
    , '2007-05-08 09:53:01.0376635');

Е. Указание числовых выражений и скалярных системных функций в качестве конечной даты

В следующем примере в качестве аргумента enddate используются числовое выражение (GETDATE ()+ 1) и скалярные системные функции GETDATE и SYSDATETIME.

USE AdventureWorks2008R2;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', GETDATE()+ 1) 
    AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO
USE AdventureWorks2008R2;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', DATEADD(day,1,SYSDATETIME())) AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO

Ж. Указание ранжирующих функций в качестве начальной даты

В следующем примере в качестве аргумента startdate используется ранжирующая функция.

USE AdventureWorks2008R2;
GO
SELECT p.FirstName, p.LastName
    ,DATEDIFF(day,ROW_NUMBER() OVER (ORDER BY 
        a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson s 
    INNER JOIN Person.Person p 
        ON s.BusinessEntityID = p.BusinessEntityID
    INNER JOIN Person.Address a 
        ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0;

З. Указание статистической оконной функции в качестве начальной даты

В следующем примере в качестве аргумента startdate используется статистическая оконная функция.

USE AdventureWorks2008R2;
GO
SELECT soh.SalesOrderID, sod.ProductID, sod.OrderQty,soh.OrderDate
    ,DATEDIFF(day,MIN(soh.OrderDate) 
        OVER(PARTITION BY soh.SalesOrderID),SYSDATETIME() ) AS 'Total'
FROM Sales.SalesOrderDetail sod
    INNER JOIN Sales.SalesOrderHeader soh
        ON sod.SalesOrderID = soh.SalesOrderID
WHERE soh.SalesOrderID IN(43659,58918);
GO

См. также

Справочник