DATEADD (Transact-SQL)
Devuelve un valor date con el intervalo number especificado (entero con firma) agregado a un valor datepart especificado de ese valor date.
Para obtener una introducción de todos los tipos de datos y funciones de fecha y hora de Transact-SQL, vea Tipos de datos y funciones de fecha y hora (Transact-SQL).
Convenciones de sintaxis de Transact-SQL
Sintaxis
DATEADD (datepart , number , date )
Argumentos
datepart
Es una parte de date al que se agrega un integer number. En la siguiente tabla se recogen los argumentos válidos de datepart. Los equivalentes de variables definidas por el usuario no son válidos.datepart
Abreviaturas
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
Expresión que se puede resolver como un valor int que se suma a un datepart de date. Las variables definidas por el usuario son válidas.Si especifica un valor con una fracción decimal, la fracción se trunca y no se redondea.
date
Es una expresión que se puede resolver como un valor time, date, smalldatetime, datetime, datetime2 o datetimeoffset. date puede ser una expresión, una expresión de columna, una variable definida por el usuario o un literal de cadena. Si la expresión es un literal de cadena, debe tener como resultado un valor datetime. Para evitar la ambigüedad, utilice años de cuatro dígitos. Parta obtener información sobre los años de dos dígitos, consulte Establecer la opción de configuración del servidor Fecha límite de año de dos dígitos.
Tipos de valor devueltos
El tipo de datos de retorno es el tipo de datos del argumento date, salvo los literales de cadena.
El tipo de datos de retorno para un literal de cadena es datetime. Se producirá un error si la escala de segundos del literal de cadena tiene más de tres posiciones (. nnn) o contiene la parte del ajuste de zona horaria.
Argumento datepart
dayofyear, day y weekday devuelven el mismo valor.
Cada datepart y sus abreviaturas devuelven el mismo valor.
Si datepart es month y el mes date tiene más días que el mes de retorno y el día date no existe en el mes de retorno, se devuelve el último día del mes de retorno. Por ejemplo, septiembre tiene 30 días; por consiguiente, las dos instrucciones siguientes devuelven 2006-09-30 00:00:00.000:
SELECT DATEADD(month, 1, '2006-08-30');
SELECT DATEADD(month, 1, '2006-08-31');
El argumento number no puede superar el intervalo de int. En las instrucciones siguientes, el argumento para number supera el intervalo de int por 1. Se devuelve un mensaje de error que indica lo siguiente: "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');
El argumento date no se puede incrementar a un valor fuera del intervalo de su tipo de datos. En las instrucciones siguientes, el valor number que se agrega al valor de date supera el intervalo del tipo de datos date. Se devuelve un mensaje de error que indica lo siguiente: "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');
La parte correspondiente a los segundos de un valor smalldatetime siempre es 00. Si date es smalldatetime, se aplica lo siguiente:
Si datepart es second y number oscila entre -30 y +29, no se realiza ninguna adición.
Si datepart es second y number es inferior a -30 o superior a +29, la suma se realiza empezando por un minuto.
Si datepart es millisecond y number oscila entre -30001 y +29998, no se realiza ninguna suma.
Si datepart es millisecond y number es inferior a -30001 o superior a +29998, la suma se realiza empezando por un minuto.
Comentarios
DATEADD se puede utilizar en las cláusulas SELECT <lista>, WHERE, HAVING, GROUP BY y ORDER BY.
Precisión de fracciones de segundo
La suma para un datepart de microsecond o nanosecond para los tipos de datos date smalldatetime, date y datetime no está permitida.
Los milisegundos tienen una escala de 3 (0,123), los microsegundos tienen una escala de 6 (0,123456) y los nanosegundos tienen una escala de 9 (0,123456789). Los tipos de datos time, datetime2 y datetimeoffset tienen una escala máxima de 7 (0,1234567). Si datepart es nanosecond, number debe ser 100 antes de que las fracciones de segundo de date aumenten. Un number entre 1 y 49 se redondea por defecto en 0 y un número de 50 a 99 se redondea por exceso en 100.
Las instrucciones siguientes agregan un datepart de millisecond, microsecond o 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);
El conjunto de resultados es el siguiente.
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
Ajuste de zona horaria
La suma no se permite para el ajuste de zona horaria.
Ejemplos
A.Aumentar datepart en un intervalo de 1
Cada una de las instrucciones siguientes incrementa datepart en un intervalo de 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);
El conjunto de resultados es el siguiente.
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
B.Aumentar más de un nivel de datepart en una instrucción
Cada una de las instrucciones siguientes incrementa datepart en un number los suficientemente grande para también incrementar el datepart más alto siguiente de 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
C.Utilizar las expresiones como argumentos para los parámetros number y date
Los ejemplos siguientes emplean tipos diferentes de expresiones como argumentos para los parámetros number y date.
Especificar una columna como fecha
En el ejemplo siguiente se agregan 2 días a cada valor de la columna OrderDate para derivar una nueva columna denominada PromisedShipDate.
USE AdventureWorks2012;
GO
SELECT SalesOrderID
,OrderDate
,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;
A continuación se muestra un conjunto de resultados parcial.
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
Especificar las variables definidas por el usuario como number y date
En el ejemplo siguiente se especifican variables definidas por el usuario como argumentos para number y date.
DECLARE @days int = 365,
@datetime datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */;
SELECT DATEADD(day, @days, @datetime);
El conjunto de resultados es el siguiente.
-----------------------
2000-12-31 01:01:01.110
(1 row(s) affected)
Especificar la función de sistema escalar como date
En el siguiente ejemplo se especifica la palabra clave SYSDATETIME para date.
SELECT DATEADD(month, 1, SYSDATETIME());
El conjunto de resultados es el siguiente.
---------------------------
2013-02-06 14:29:59.6727944
(1 row(s) affected)
Especificar subconsultas y funciones escalares como number y date
En el ejemplo siguiente se usan subconsultas escalares, MAX(ModifiedDate), como argumentos de number y date. (SELECT TOP 1 BusinessEntityID FROM Person.Person) es un argumento artificial para el parámetro number que se usa para mostrar cómo se selecciona un argumento number de una lista de valores.
USE AdventureWorks2012;
GO
SELECT DATEADD(month,(SELECT TOP 1 BusinessEntityID FROM Person.Person),
(SELECT MAX(ModifiedDate) FROM Person.Person));
Especificar expresiones numéricas y funciones del sistema escalares como number y date
En el ejemplo siguiente se utiliza una expresión numérica (-(10/2)), operadores unarios (-), un operador aritmético (/) y funciones del sistema escalares (SYSDATETIME) como argumentos para number y date.
SELECT DATEADD(month,-(10/2), SYSDATETIME());
Especificar las funciones de clasificación como number
El ejemplo siguiente utiliza una función de clasificación como argumentos para 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;
Especificar una función de ventana agregada como number
En el ejemplo siguiente se utiliza una función de agregado como argumento para 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