DATEADD (Transact-SQL)
適用於:SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics Platform System (PDW) Microsoft Fabric 的 SQL 端點分析 Microsoft Fabric 的倉儲
此函式會將 number (帶正負號的整數) 新增至輸入 date 的 datepart,並且傳回修改過的日期/時間值。 例如,您可以使用此函式來尋找從今天起 7,000 分鐘的日期: number = 7000、 datepart = minute、 date = today。
如需所有 Transact-SQL 日期和時間數據類型和函式的概觀,請參閱 日期和時間 數據類型和函式。
語法
DATEADD (datepart , number , date )
引數
datepart
加入 int 數位的日期DATEADD
部分。 此表格會列出所有有效的 datepart 引數。
注意
DATEADD
不會接受 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 (DATEADD
要加到 date 的 datepart) 的運算式。 DATEADD
接受 number 的使用者定義變數值。 DATEADD
截斷具有小數點的指定 數位 值。 在此情況下,它不會四捨五入 數位 值。
date
可解析成下列其中一個值的運算式:
- date
- datetime
- datetimeoffset
- datetime2
- smalldatetime
- time
對於 date, DATEADD
接受數據行表達式、運算式、字串常值或使用者定義變數。 字串常值必須解析成 datetime。 請使用四位數年份以避免模糊不清的問題。 如需兩位數年份的相關信息,請參閱設定兩位數年份截止(伺服器組態選項)。
傳回類型
這個方法的傳回值資料類型為動態。 傳回型別取決於提供給 date
的引數而定。 如果 date
的值是字串常值日期,則 DATEADD
會傳回 datetime 值。 如果提供其他有效輸入資料類型給 date
,則 DATEADD
會傳回相同的資料類型。 如果字串常值的秒數小數位數超過三個小數位數位置 (.nnn),者字串常值包含時區時差部分,則 DATEADD
會引發錯誤。
傳回值
datepart 引數
dayofyear
、 day
和會 weekday
傳回相同的值。
每個 datepart 及其縮寫都會傳回相同的值。
如果下列條件成立:
- datepart 為
month
- date 月的天數多於傳回月份
- 傳 回月份中不存在日期 日期
DATEADD
則會傳回該傳回月份的最後一天。 例如,9 月有 30 (30) 天:因此,這些語句會傳回 2024-09-30 00:00:00.000
:
SELECT DATEADD(month, 1, '20240830');
SELECT DATEADD(month, 1, '2024-08-31');
number 引數
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, '20240731');
SELECT DATEADD(year, -2147483649, '20240731');
date 引數
DATEADD
不接受 遞增為數據類型範圍以外的值日期 自變數。 在下列陳述式中,加到 date 值的 number 值超過 date 資料類型的範圍。 DATEADD
會傳回下列錯誤訊息: Msg 517, Level 16, State 1, Line 1 Adding a value to a 'datetime' column caused overflow.
SELECT DATEADD(year, 2147483647, '20240731');
SELECT DATEADD(year, -2147483647, '20240731');
傳回 smalldatetime 日期和秒或小數秒 datepart 的值
smalldatetime 值的秒數部分一律為 00。 針對 smalldatetime 日期值,適用下列專案:
若為 的
second
datepart,以及介於 -30 和 +29 之間的數位值,DATEADD
則不會變更。對於 的
second
datepart,以及小於 -30 或大於 +29 的數位值,DATEADD
會從一分鐘開始執行其加法。對於 的 datepart
millisecond
和介於 -30001 到 +29998 之間的數位值,DATEADD
則不會變更。若為 的 datepart
millisecond
和小於 -30001 的數位值,或超過 +29998,DATEADD
則會從一分鐘開始執行其加法。
備註
在下列子句中使用 DATEADD
:
GROUP BY
HAVING
ORDER BY
SELECT <list>
WHERE
小數秒數有效位數
DATEADD
不允許新增 datepart 或 nanosecond
microsecond
date 數據類型 smalldatetime、date 和 datetime。
毫秒的刻度為 3 (.123
),微秒的尺規為 6 (.123456
),納米秒的尺規為 9 (.123456789
)。 time、datetime2 和 datetimeoffset 資料類型的最大小數字數為 7 (.1234567
)。 對於 的 nanosecond
datepart,number 必須是 100,日期增加的小數秒之前。 介於 1 到 49 之間的數位 會捨入到 0,而數位從 50 到 99 捨入到 100。
這些語句會加入 、 microsecond
或 nanosecond
的 millisecond
datepart。
DECLARE @datetime2 DATETIME2 = '2024-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 2024-01-01 13:10:10.1121111
2 milliseconds 2024-01-01 13:10:10.1131111
1 microsecond 2024-01-01 13:10:10.1111121
2 microseconds 2024-01-01 13:10:10.1111131
49 nanoseconds 2024-01-01 13:10:10.1111111
50 nanoseconds 2024-01-01 13:10:10.1111112
150 nanoseconds 2024-01-01 13:10:10.1111113
時區位移
DATEADD
不允許新增時區位移。
範例
A. 以間隔 1 遞增 datepart
以下每個陳述式都會以 1 為間隔遞增 datepart:
DECLARE @datetime2 DATETIME2 = '2024-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 2025-01-01 13:10:10.1111111
quarter 2024-04-01 13:10:10.1111111
month 2024-02-01 13:10:10.1111111
dayofyear 2024-01-02 13:10:10.1111111
day 2024-01-02 13:10:10.1111111
week 2024-01-08 13:10:10.1111111
weekday 2024-01-02 13:10:10.1111111
hour 2024-01-01 14:10:10.1111111
minute 2024-01-01 13:11:10.1111111
second 2024-01-01 13:10:11.1111111
millisecond 2024-01-01 13:10:10.1121111
microsecond 2024-01-01 13:10:10.1111121
nanosecond 2024-01-01 13:10:10.1111111
B. 在一個語句中遞增一個以上的 datepart 層級
以下每個陳述式都會利用足以同時遞增 date 中下一個較高 datepart 的 number來遞增 datepart:
DECLARE @datetime2 DATETIME2;
SET @datetime2 = '2024-01-01 01:01:01.1111111';
--Statement Result
-------------------------------------------------------------------
SELECT DATEADD(quarter, 4, @datetime2); --2025-01-01 01:01:01.1111111
SELECT DATEADD(month, 13, @datetime2); --2025-02-01 01:01:01.1111111
SELECT DATEADD(dayofyear, 366, @datetime2); --2025-01-01 01:01:01.1111111
SELECT DATEADD(day, 366, @datetime2); --2025-01-01 01:01:01.1111111
SELECT DATEADD(week, 5, @datetime2); --2024-02-05 01:01:01.1111111
SELECT DATEADD(weekday, 31, @datetime2); --2024-02-01 01:01:01.1111111
SELECT DATEADD(hour, 23, @datetime2); --2024-01-02 00:01:01.1111111
SELECT DATEADD(minute, 59, @datetime2); --2024-01-01 02:00:01.1111111
SELECT DATEADD(second, 59, @datetime2); --2024-01-01 01:02:00.1111111
SELECT DATEADD(millisecond, 1, @datetime2); --2024-01-01 01:01:01.1121111
C. 使用運算式當做 number 和 date 參數的引數
這些範例會使用不同的運算式類型,作為 number 和 date 參數的引數。 範例使用的是 AdventureWorks 資料庫。
將資料行指定為 date
此範例會將 2
兩天加到 OrderDate
資料行中的每個值,以便衍生名為 PromisedShipDate
的新資料行:
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
將純量系統函數指定為 date
這個範例會針對 date 指定 SYSDATETIME
。 傳回的精確值取決於陳述式執行的日期和時間:
SELECT DATEADD(month, 1, SYSDATETIME());
結果集如下所示。
2024-04-25 14:29:59.6727944
將純量子查詢和純量函數指定為 number 和 date
此範例會使用純量子查詢 MAX(ModifiedDate)
,作為 number 和 date 的引數。 (SELECT TOP 1 BusinessEntityID FROM Person.Person)
會作為 number 參數的人工引數,以示範如何從值清單中選取 number 引數。
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 的引數。
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 的引數。
SELECT SalesOrderID,
ProductID,
OrderQty,
DATEADD(day, SUM(OrderQty) OVER (PARTITION BY SalesOrderID), SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43659, 43664);
GO