DATEDIFF (Transact-SQL)
Возвращает количество (целое число со знаком) указанных границ datepart, пересеченных между startdate и enddate.
Обзор всех типов данных и функций даты и времени в языке 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