DATEADD (Transact-SQL)
傳回指定的 date,並將指定的 number 間隔 (帶正負號的整數) 加入至該 date 的指定 datepart。
如需所有 Transact-SQL 日期和時間資料類型與函數的概觀,請參閱<日期和時間資料類型與函數 (Transact-SQL)>。
語法
DATEADD (datepart , number , date )
引數
datepart
這是 integer number 要加入其中的 date 部分。 下表列出所有有效的 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 (要加入至 date 的 datepart) 的運算式。 使用者自訂的變數有效。如果您指定了含有十進位小數的值,該小數就會被截斷而且不會四捨五入。
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 引數不得遞增為超過其資料類型之範圍的值。 在下列陳述式中,加入至 date 值的 number 值超過 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 <list>、WHERE、HAVING、GROUP BY 和 ORDER BY 子句中。
小數秒數有效位數
不允許針對 date 資料類型 smalldatetime、date 和 datetime 的 microsecond 或 nanosecond datepart 執行加法。
毫秒具有小數位數 3 (.123),微秒具有小數位數 6 (.123456),奈秒具有小數位數 9 (.123456789)。 time、datetime2 和 datetimeoffset 資料類型都具有最大小數位數 7 (.1234567)。 如果 datepart 是 nanosecond,在 date 的小數秒數增加之前,number 必須是 100。 介於 1 與 49 之間的 number 會向下捨入到 0,而 50 至 99 之間的數字則會向上捨入到 100。
下列陳述式會加入 millisecond、microsecond 或 nanosecond 的 datepart。
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
時區位移
不允許針對時區位移執行加法。
範例
A.以 1 為間隔遞增 datepart
下列每個陳述式都會以 1 為間隔遞增 datepart。
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
B.在單一陳述式中遞增一個以上的 datepart 層級
下列每個陳述式都會利用足以同時遞增 date 中下一個較高 datepart 的 number,遞增 datepart。
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.使用運算式當做 number 和 date 參數的引數
下列範例會使用不同的運算式類型,當做 number 和 date 參數的引數。
指定資料行成為 date
下列範例會將 2 天加入至 OrderDate 資料行中的每個值,以便衍生名為 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 參數的人工引數,可說明如何從值清單中選取 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