DATEADD (Transact-SQL)

適用於:SQL ServerAzure SQL 資料庫Azure SQL 受控執行個體Azure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric 中的 SQL 分析端點Microsoft Fabric 中的倉儲

此函式會將 number (帶正負號的整數) 新增至輸入 datedatepart,並且傳回修改過的日期/時間值。 例如,您可以使用此函式來尋找從今天起 7,000 分鐘的日期: number = 7000、 datepart = minute、 date = today。

如需所有 Transact-SQL 日期和時間數據類型和函式的概觀,請參閱 日期和時間 數據類型和函式。

Transact-SQL 語法慣例

Syntax

DATEADD (datepart , number , date )

注意

若要檢視 SQL Server 2014 (12.x) 和舊版的 Transact-SQL 語法,請參閱 舊版檔

引數

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 要加到 datedatepart) 的運算式。 DATEADD 接受 number 的使用者定義變數值。 DATEADD 截斷具有小數點的指定 數位 值。 在此情況下,它不會四捨五入 數位 值。

date

可解析成下列其中一個值的運算式:

  • date
  • datetime
  • datetimeoffset
  • datetime2
  • smalldatetime
  • time

對於 dateDATEADD 接受數據行表達式、運算式、字串常值或使用者定義變數。 字串常值必須解析成 datetime。 請使用四位數年份以避免模糊不清的問題。 如需兩位數年份的相關信息,請參閱設定兩位數年份截止(伺服器組態選項)。

傳回類型

這個方法的傳回值資料類型為動態。 傳回型別取決於提供給 date 的引數而定。 如果 date 的值是字串常值日期,則 DATEADD 會傳回 datetime 值。 如果提供其他有效輸入資料類型給 date,則 DATEADD 會傳回相同的資料類型。 如果字串常值的秒數小數位數超過三個小數位數位置 (.nnn),者字串常值包含時區時差部分,則 DATEADD 會引發錯誤。

傳回值

datepart 引數

dayofyearday和會 weekday 傳回相同的值。

每個 datepart 及其縮寫都會傳回相同的值。

如果下列條件成立:

  • datepartmonth
  • 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。 對於 smalldatetimedate 值,適用下列情況:

  • 若為 seconddatepart,以及介於 -30 和 +29 之間的數位值,DATEADD則不會變更。

  • 對於 的 seconddatepart,以及小於 -30 或大於 +29 的數位值,DATEADD會從一分鐘開始執行其加法。

  • 對於 的 datepartmillisecond介於 -30001 到 +29998 之間的數位值,DATEADD則不會變更。

  • 若為 的 datepart millisecond小於 -30001 的數位值,或超過 +29998,DATEADD則會從一分鐘開始執行其加法。

備註

在下列子句中使用 DATEADD

  • GROUP BY
  • HAVING
  • ORDER BY
  • SELECT <list>
  • WHERE

小數秒數有效位數

DATEADD不允許新增 datepartnanosecondmicrosecond date 數據類型 smalldatetimedatedatetime。

毫秒的刻度為 3 (.123),微秒的尺規為 6 (.123456),納米秒的尺規為 9 (.123456789)。 time、datetime2 和 datetimeoffset 資料類型的最大小數字數為 7 (.1234567)。 對於 的 nanoseconddatepart,number 必須是 100,日期增加的小數秒之前。 介於 1 到 49 之間的數位 會捨入到 0,而數位從 50 到 99 捨入到 100。

這些語句會加入 microsecondnanosecondmilliseconddatepart

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 中下一個較高 datepartnumber來遞增 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, 365, @datetime2); --2025-01-01 01:01:01.1111111
SELECT DATEADD(day, 365, @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 參數的引數

這些範例會使用不同的運算式類型,作為 numberdate 參數的引數。 範例使用的是 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

此範例會將使用者定義變數指定為 numberdate 的引數:

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),作為 numberdate 的引數。 (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/) 做為 numberdate自變數。

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