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


DATEADD (Transact-SQL)

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

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

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

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

Синтаксис

DATEADD (datepart , number , date )

Аргументы

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

    datepart

    Сокращения

    year

    yy, yyyy

    quarter

    qq, q

    month

    mm, m

    dayofyear

    dy, y

    day

    dd, d

    week

    wk, ww

    weekday

    dw, w

    hour

    hh

    minute

    mi, n

    second

    ss, s

    millisecond

    ms

    microsecond

    mcs

    nanosecond

    ns

  • number
    Выражение, которое преобразуется к типу int и добавляется к компоненту datepart даты date. Допускаются пользовательские переменные.

    Если указать значения с десятичной дробью, дробь усекается, а не округляется.

  • date
    Выражение, которое можно привести к значению типа time, date, smalldatetime, datetime, datetime2 или datetimeoffset. Аргумент date может быть выражением, выражением столбца, определяемой пользователем переменной или строковым литералом. Если выражение является строковым литералом, его результатом должно быть значение типа datetime. Во избежание неоднозначности используйте четырехзначную запись года. Дополнительные сведения о двузначном обозначении года см. в разделе Настройка параметра конфигурации сервера two digit year cutoff.

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

Тип возвращаемых данных является типом аргумента date, за исключением строковых литералов.

Тип возвращаемых данных для строкового литерала имеет тип datetime. Если строковый литерал имеет более трех позиций долей секунды (. nnn) или содержит компонент смещения часового пояса, возникнет ошибка.

Аргумент datepart

Функции dayofyear, day и weekday возвращают одинаковое значение.

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

Если datepart имеет тип month, а в месяце даты date имеется больше дней, чем в возвращаемом месяце, и день даты date не существует в этом месяце, возвращается последний день месяца. Например, в сентябре 30 дней, поэтому следующие две инструкции возвращают 2006-09-30 00:00:00.000:

SELECT DATEADD(month, 1, '2006-08-30');

SELECT DATEADD(month, 1, '2006-08-31');

Аргумент number не может выходить за диапазон типа данных int. В следующих инструкциях аргумент number превышает диапазон типа данных int на 1. Выдается следующее сообщение об ошибке: "Msg 8115, Level 16, State 2, Line 1. Arithmetic overflow error converting expression to data type int."

SELECT DATEADD(year,2147483648, '2006-07-31');
SELECT DATEADD(year,-2147483649, '2006-07-31');

Аргумент date не может быть увеличен до значения, выходящего за диапазон соответствующего типа данных. В следующих инструкциях значение number прибавляется к значению date, в результате превышается диапазон типа данных date. Выдается следующее сообщение об ошибке: "Msg 517, Level 16, State 1, Line 1 Adding a value to a 'datetime' column caused overflow."

SELECT DATEADD(year,2147483647, '2006-07-31');
SELECT DATEADD(year,-2147483647, '2006-07-31');

Значение секунд даты типа smalldatetime всегда равно 00. Если аргумент date имеет тип smalldatetime, действуют следующие условия.

  • Если datepart имеет значение second и number лежит между -30 и +29, добавление не выполняется.

  • Если datepart имеет значение second и number менее -30 или более +29, выполняется добавление времени, начиная с одной минуты.

  • Если datepart имеет значение millisecond и number лежит между -30001 и +29998, добавление не выполняется.

  • Если datepart имеет значение millisecond и number менее -30001 или более +29998, выполняется добавление времени, начиная с одной минуты.

Замечания

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

Точность в долях секунды

Использование при сложении в качестве аргумента datepart значений microsecond или nanosecond для типов данных date: smalldatetime, date и datetime не допускается.

Миллисекунды имеют точность 3 знака (0,123), микросекунды — 6 знаков (0,123456), наносекунды — 9 знаков (0,123456789). Типы данных time, datetime2 и datetimeoffset имеют максимальную точность 7 знаков (0,1234567). Если аргументом datepart является nanosecond, аргумент number должен иметь значение 100 перед увеличением даты date на доли секунды. Значение аргумента number, находящееся в пределах 1 до 49, округляется до 0, а значение от 50 до 99 округляется до 100.

Следующие инструкции добавляют часть даты datepart: millisecond, microsecond или nanosecond.

DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111';
SELECT '1 millisecond', DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT '2 milliseconds', DATEADD(millisecond,2,@datetime2)
UNION ALL
SELECT '1 microsecond', DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT '2 microseconds', DATEADD(microsecond,2,@datetime2)
UNION ALL
SELECT '49 nanoseconds', DATEADD(nanosecond,49,@datetime2)
UNION ALL
SELECT '50 nanoseconds', DATEADD(nanosecond,50,@datetime2)
UNION ALL
SELECT '150 nanoseconds', DATEADD(nanosecond,150,@datetime2);

Ниже приводится результирующий набор.

1 millisecond     2007-01-01 13:10:10.1121111
2 milliseconds    2007-01-01 13:10:10.1131111
1 microsecond     2007-01-01 13:10:10.1111121
2 microseconds    2007-01-01 13:10:10.1111131
49 nanoseconds    2007-01-01 13:10:10.1111111
50 nanoseconds    2007-01-01 13:10:10.1111112
150 nanoseconds   2007-01-01 13:10:10.1111113

Смещение часового пояса

При смещении часового пояса добавление не допускается.

Примеры

А.Увеличение части даты на интервал, равный 1

Каждая следующая инструкция увеличивает часть даты datepart на интервал, равный 1.

DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111';
SELECT 'year', DATEADD(year,1,@datetime2)
UNION ALL
SELECT 'quarter',DATEADD(quarter,1,@datetime2)
UNION ALL
SELECT 'month',DATEADD(month,1,@datetime2)
UNION ALL
SELECT 'dayofyear',DATEADD(dayofyear,1,@datetime2)
UNION ALL
SELECT 'day',DATEADD(day,1,@datetime2)
UNION ALL
SELECT 'week',DATEADD(week,1,@datetime2)
UNION ALL
SELECT 'weekday',DATEADD(weekday,1,@datetime2)
UNION ALL
SELECT 'hour',DATEADD(hour,1,@datetime2)
UNION ALL
SELECT 'minute',DATEADD(minute,1,@datetime2)
UNION ALL
SELECT 'second',DATEADD(second,1,@datetime2)
UNION ALL
SELECT 'millisecond',DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT 'microsecond',DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT 'nanosecond',DATEADD(nanosecond,1,@datetime2);

Ниже приводится результирующий набор.

Year         2008-01-01 13:10:10.1111111
quarter      2007-04-01 13:10:10.1111111
month        2007-02-01 13:10:10.1111111
dayofyear    2007-01-02 13:10:10.1111111
day          2007-01-02 13:10:10.1111111
week         2007-01-08 13:10:10.1111111
weekday      2007-01-02 13:10:10.1111111
hour         2007-01-01 14:10:10.1111111
minute       2007-01-01 13:11:10.1111111
second       2007-01-01 13:10:11.1111111
millisecond  2007-01-01 13:10:10.1121111
microsecond  2007-01-01 13:10:10.1111121
nanosecond   2007-01-01 13:10:10.1111111

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

Каждая следующая инструкция увеличивает часть даты datepart на число number, достаточно большое, чтобы увеличить следующую часть даты datepart даты date.

DECLARE @datetime2 datetime2;
SET @datetime2 = '2007-01-01 01:01:01.1111111';
--Statement                                 Result   
------------------------------------------------------------------- 
SELECT DATEADD(quarter,4,@datetime2);     --2008-01-01 01:01:01.110
SELECT DATEADD(month,13,@datetime2);      --2008-02-01 01:01:01.110
SELECT DATEADD(dayofyear,365,@datetime2); --2008-01-01 01:01:01.110
SELECT DATEADD(day,365,@datetime2);       --2008-01-01 01:01:01.110
SELECT DATEADD(week,5,@datetime2);        --2007-02-05 01:01:01.110
SELECT DATEADD(weekday,31,@datetime2);    --2007-02-01 01:01:01.110
SELECT DATEADD(hour,23,@datetime2);       --2007-01-02 00:01:01.110
SELECT DATEADD(minute,59,@datetime2);     --2007-01-01 02:00:01.110
SELECT DATEADD(second,59,@datetime2);     --2007-01-01 01:02:00.110
SELECT DATEADD(millisecond,1,@datetime2); --2007-01-01 01:01:01.110

В.Использование выражений в качестве аргументов number и date

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

Указание столбца в качестве аргумента date

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

USE AdventureWorks2012;
GO
SELECT SalesOrderID
    ,OrderDate 
    ,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;

Здесь приводится частичный результирующий набор.

SalesOrderID OrderDate               PromisedShipDate
------------ ----------------------- -----------------------
43659        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43660        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43661        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
...
43702        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43703        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43704        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43705        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43706        2005-07-03 00:00:00.000 2005-07-05 00:00:00.000
...
43711        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
43712        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
...
43740        2005-07-11 00:00:00.000 2005-07-13 00:00:00.000
43741        2005-07-12 00:00:00.000 2005-07-14 00:00:00.000

Указание пользовательских переменных в качестве аргументов number и date

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

DECLARE @days int = 365, 
        @datetime datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */;
SELECT DATEADD(day, @days, @datetime);

Ниже приводится результирующий набор.

-----------------------
2000-12-31 01:01:01.110

(1 row(s) affected)

Указание в качестве аргумента date скалярной системной функции

В следующем примере в качестве аргумента date указывается SYSDATETIME.

SELECT DATEADD(month, 1, SYSDATETIME());

Ниже приводится результирующий набор.

---------------------------
2013-02-06 14:29:59.6727944

(1 row(s) affected)

Указание в качестве аргументов number и date скалярных вложенных запросов и скалярных функций

В следующем примере скалярные вложенные запросы MAX(ModifiedDate) служат аргументами для number и date. (SELECT TOP 1 BusinessEntityID FROM Person.Person) является искусственным аргументом для числового параметра, показывающим способ выбора аргумента number из списка значений.

USE AdventureWorks2012;
GO
SELECT DATEADD(month,(SELECT TOP 1 BusinessEntityID FROM Person.Person),
    (SELECT MAX(ModifiedDate) FROM Person.Person));

Указание в качестве аргументов number и date числовых выражений и скалярных системных функций

В следующем примере числовое выражение (-(10/2)), унарные операторы (-), арифметический оператор (/) и скалярные системные функции (SYSDATETIME) используются в качестве аргументов number и date.

SELECT DATEADD(month,-(10/2), SYSDATETIME());

Указание в качестве аргумента number ранжирующих функций

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

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

Указание в качестве аргумента number статистической оконной функции

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

USE AdventureWorks2012;
GO
SELECT SalesOrderID, ProductID, OrderQty
    ,DATEADD(day,SUM(OrderQty) 
        OVER(PARTITION BY SalesOrderID),SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN(43659,43664);
GO

См. также

Справочник

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