DATEADD (Transact-SQL)
Gibt einen angegebenen date-Wert zurück, wobei das angegebene number-Intervall (ganze Zahl mit Vorzeichen) einem angegebenen datepart-Wert für diesen date-Wert hinzugefügt wird.
Eine Übersicht über alle Datums- und Uhrzeitdatentypen und die zugehörigen Funktionen von Transact-SQL finden Sie unter Datums- und Uhrzeitdatentypen und zugehörige Funktionen (Transact-SQL).
Gilt für: SQL Server (SQL Server 2008 bis aktuelle Version), Windows Azure SQL-Datenbank (Ursprüngliche Version bis aktuelle Version). |
Transact-SQL-Syntaxkonventionen
Syntax
DATEADD (datepart , number , date )
Argumente
datepart
Der Teil von date, dem ein integer number hinzugefügt wird. In der folgenden Tabelle sind alle gültigen datepart-Argumente aufgeführt. Benutzerdefinierte Variablenentsprechungen sind nicht gültig.datepart
Abkürzungen
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
Ein Ausdruck, der in einen int-Wert aufgelöst werden kann, der einem datepart-Wert vom Datentyp date hinzugefügt wird. Benutzerdefinierte Variablen sind gültig.Wenn Sie einen Wert mit einem Dezimalbruch angeben, wird der Bruch abgeschnitten und nicht gerundet.
date
Ein Ausdruck, der in einen time-Wert, date-Wert, smalldatetime-Wert, datetime-Wert, datetime2-Wert oder datetimeoffset-Wert aufgelöst werden kann. date kann ein Ausdruck, ein Spaltenausdruck, eine benutzerdefinierte Variable oder ein Zeichenfolgenliteral sein. Wenn der Ausdruck ein Zeichenfolgenliteral ist, muss er in datetime aufgelöst werden. Um Mehrdeutigkeiten zu vermeiden, sollten Sie vierstellige Jahreszahlen verwenden. Informationen zu zweistelligen Jahreszahlen finden Sie unter Konfigurieren der Serverkonfigurationsoption Umstellungsjahr für Angaben mit zwei Ziffern.
Rückgabetypen
Beim Rückgabedatentyp handelt es sich um den Datentyp des date-Arguments. Eine Ausnahme bilden hier Zeichenfolgenliterale.
Der Rückgabedatentyp für ein Zeichenfolgenliteral ist datetime. Wenn die Dezimalstellen für die Sekunden des Zeichenfolgenliterals mehr als drei Positionen (. nnn) umfassen oder einen Zeitzonenoffset-Teil enthalten, wird ein Fehler ausgelöst.
datepart-Argument
dayofyear, day und weekday geben denselben Wert zurück.
Jedes datepart-Argument und die zugehörigen Abkürzungen geben denselben Wert zurück.
Wenn datepart den Wert month aufweist und der für date angegebene Monat mehr Tage umfasst als der Rückgabemonat und der für date angegebene Tag nicht im Rückgabemonat vorhanden ist, wird der letzte Tag des Rückgabemonats zurückgegeben. Beispiel: Der September hat 30 Tage. Daher geben die beiden folgenden Anweisungen 2006-09-30 00:00:00.000 zurück:
SELECT DATEADD(month, 1, '2006-08-30');
SELECT DATEADD(month, 1, '2006-08-31');
Das number-Argument kann den Bereich von int nicht überschreiten. In den folgenden Anweisungen überschreitet das Argument für number den Bereich von int um 1. Die folgende Fehlermeldung wird zurückgegeben: "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');
Das date-Argument kann nicht zu einem Wert außerhalb des Bereichs seines Datentyps inkrementiert werden. In den folgenden Anweisungen überschreitet der number-Wert, der dem date-Wert hinzugefügt wird, den Bereich des date-Datentyps. Die folgende Fehlermeldung wird zurückgegeben: "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');
Die Sekundenangabe eines smalldatetime-Werts ist immer 00. Wenn date den Wert smalldatetime hat, gilt Folgendes:
Wenn datepart den Wert second hat und number zwischen -30 und +29 liegt, findet keine Addition statt.
Wenn datepart den Wert second hat und number unter -30 oder über +29 liegt, findet eine bei einer Minute beginnende Addition statt.
Wenn datepart den Wert millisecond hat und number zwischen -30001 und +29998 liegt, findet keine Addition statt.
Wenn datepart den Wert millisecond hat und number unter -30001 oder über +29998 liegt, findet eine bei einer Minute beginnende Addition statt.
Hinweise
DATEADD kann in den Klauseln SELECT <Liste>, WHERE, HAVING, GROUP BY und ORDER BY verwendet werden.
Genauigkeit in Sekundenbruchteilen
Für einen datepart-Wert microsecond oder nanosecond für die date-Datentypen smalldatetime, date und datetime ist Addition nicht zulässig.
Millisekunden besitzen drei Dezimalstellen (.123). Mikrosekunden besitzen sechs Dezimalstellen (.123456). Nanosekunden besitzen neun Dezimalstellen (.123456789). Die Datentypen time, datetime2 und datetimeoffset besitzen maximal sieben Dezimalstellen (.1234567). Wenn datepart den Wert nanosecond hat, muss number 100 sein, bevor die Sekundenbruchteile von date erhöht werden. Hat number einen Wert zwischen 1 und 49, wird er auf 0 abgerundet. Eine Zahl zwischen 50 und 99 wird auf 100 aufgerundet.
Durch die folgenden Anweisungen wird datepart mit millisecond, microsecond oder nanosecond hinzugefügt.
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);
Dies ist das Resultset.
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
Zeitzonenoffset
Für einen Zeitzonenoffset ist Addition nicht zulässig.
Beispiele
A.Inkrementieren von datepart mit einem Intervall von 1
Jede der folgenden Anweisungen inkrementiert datepart mit einem Intervall von 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);
Dies ist das Resultset.
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.Inkrementieren mehrerer Ebenen von datepart in einer Anweisung
Jede der folgenden Anweisungen inkrementiert datepart um einen number-Wert, der hoch genug ist, um auch den nächsthöheren datepart-Wert von date zu inkrementieren.
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.Verwenden von Ausdrücken als Argumente für den number-Parameter und den date-Parameter
In den folgenden Beispielen werden verschiedene Typen von Ausdrücken als Argumente für den number-Parameter und den date-Parameter verwendet.
Angeben einer Spalte als date-Parameter
Im folgenden Beispiel werden zu jedem Wert in der OrderDate-Spalte 2 Tage hinzuaddiert, um eine neue Spalte mit dem Namen PromisedShipDate abzuleiten.
USE AdventureWorks2012;
GO
SELECT SalesOrderID
,OrderDate
,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;
Dies ist ein Auszug aus dem Resultset.
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
Angeben von benutzerdefinierten Variablen als Argumente für number und date
Im folgenden Beispiel werden benutzerdefinierte Variablen als Argumente für number und date angegeben.
DECLARE @days int = 365,
@datetime datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */;
SELECT DATEADD(day, @days, @datetime);
Dies ist das Resultset.
-----------------------
2000-12-31 01:01:01.110
(1 row(s) affected)
Angeben einer skalaren Systemfunktion als Argument für date
Im folgenden Beispiel wird SYSDATETIME für date angegeben.
SELECT DATEADD(month, 1, SYSDATETIME());
Dies ist das Resultset.
---------------------------
2013-02-06 14:29:59.6727944
(1 row(s) affected)
Angeben von skalaren Unterabfragen und skalaren Funktionen als Argumente für number und date
Im folgenden Beispiel werden skalare Unterabfragen, MAX(ModifiedDate), als Argumente für number und date verwendet. (SELECT TOP 1 BusinessEntityID FROM Person.Person) ist ein Beispielargument für den number-Parameter, das veranschaulichen soll, wie ein number-Argument aus einer Werteliste ausgewählt wird.
USE AdventureWorks2012;
GO
SELECT DATEADD(month,(SELECT TOP 1 BusinessEntityID FROM Person.Person),
(SELECT MAX(ModifiedDate) FROM Person.Person));
Angeben von numerischen Ausdrücken und skalaren Systemfunktionen als Argumente für number und date
Im folgenden Beispiel werden numerische Ausdrücke (-(10/2)), unäre Operatoren (-), ein arithmetischer Operator (/) und skalare Systemfunktionen (SYSDATETIME) als Argumente für number und date verwendet.
SELECT DATEADD(month,-(10/2), SYSDATETIME());
Angeben von Rangfolgefunktionen als Argumente für number
Im folgenden Beispiel wird eine Rangfolgefunktion als Argument für number verwendet.
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;
Angeben einer Aggregatfensterfunktion als Argument für number
Im folgenden Beispiel wird eine Aggregatfensterfunktion als Argument für number verwendet.
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