DATEDIFF (Transact-SQL)

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

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

Применимо для следующих объектов: SQL Server (SQL Server 2008 по текущую версию), База данных SQL Windows Azure (С первоначального выпуска по текущий выпуск).

Значок ссылки на раздел Синтаксические обозначения в 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, а также при составлении списка выбора.

Функция DATEDIFF неявно приводит строковые литералы к типу datetime2. Это означает, что при передаче даты в виде строки DATEDIFF не поддерживает формат ГЧМ (год, число, месяц). Для использования формата ГЧМ (год, число, месяц) необходимо явно привести строку к типу datetime или smalldatetime.

Указание SET DATEFIRST не влияет на DATEDIFF. DATEDIFF всегда считает воскресенье первым днем недели, чтобы обеспечить детерминистичность работы функции.

Примеры

В следующих примерах выражения различного типа используются в качестве аргументов для параметров 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 AdventureWorks2012;
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 AdventureWorks2012;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', GETDATE()+ 1) 
    AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO
USE AdventureWorks2012;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', DATEADD(day,1,SYSDATETIME())) AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO

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

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

USE AdventureWorks2012;
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 AdventureWorks2012;
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

См. также

Справочник

Функции CAST и CONVERT (Transact-SQL)