DATEADD (Transact-SQL) - SQL Server

DATEADD (Transact-SQL) - SQL Server

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse Analytics分析平台系统(PDW)Microsoft Fabric 中的 SQL 分析终结点Microsoft Fabric 中的仓库Microsoft Fabric 中的 SQL 数据库

此函数将数​​字(有符号整数)添加到输入日期的日期部分,并返回修改后的日期/时间值 。 例如,可以使用此函数查找从今天开始的 7,000 分钟日期:number = 7000,datepart = minute,date = today。

该函数在输入日期的日期部分上添加一个数字(带符号的bigint),并返回修改后的日期/时间值。 例如,可以使用此函数查找从今天开始的 7,000 分钟日期:number = 7000,datepart = minute,date = today。

有关所有 Transact-SQL 日期和时间数据类型和函数的概述,请参阅 日期和时间数据类型和函数 。

Transact-SQL 语法约定

Syntax

DATEADD ( datepart , number , date )

Arguments

datepart

向其中添加 int DATEADD 数字的日期部分。

日期部分会加上一个大字数。DATEADD

此表列出了所有有效的 datepart 参数 。 对于 datepart 参数,DATEADD 不接受用户定义的变量等效项。

datepart

Abbreviations

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

一个表达式,可解析为 将其与 date 的 datepart 相加的 DATEADD 。 对于 number,DATEADD 接受 用户定义的变量值 。

DATEADD 会截断带小数部分的指定 number 值。 在这种情况下,它不会对数字值进行舍入。

一个可以解析为bigint的表达式,添加DATEADD日期部分的日期部分。 对于 number,DATEADD 接受 用户定义的变量值 。

DATEADD 会截断带小数部分的指定 number 值。 在这种情况下,它不会对数字值进行舍入。

date

可解析为下列值之一的表达式:

date

datetime

datetimeoffset

datetime2

smalldatetime

time

对于 日期, DATEADD 接受列表达式、表达式、字符串文本或用户定义的变量。 字符串文字值必须解析为 datetime 。 使用四位数年份可避免含糊不清问题。 有关两位数年份的信息 ,请参阅服务器配置:两位数年份截止 。

返回类型

此方法的返回值数据类型是动态的。 返回类型取决于为 date 提供的参数。 如果 date 的值是字符串文本日期,则 DATEADD 返回日期/时间值 。 如果为 date 提供了其他的有效输入数据类型,则 DATEADD 返回相同的数据类型。

DATEADD 如果字符串文本秒刻度超过三个小数位位置(.nnn)或字符串文本包含时区偏移部分,则引发错误。

返回值

datepart 参数

dayofyear, day并 weekday 返回相同的值。

每个 datepart 及其缩写都返回相同的值 。

如果以下各项为 true:

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 的范围。在以下语句中,数字的参数超过了 int 到 1 的范围。

SELECT DATEADD(year, 2147483648, '20240731');

SELECT DATEADD(year, -2147483649, '20240731');

这些语句都返回以下错误消息:

Msg 8115, Level 16, State 2, Line 1

Arithmetic overflow error converting expression to data type int.

数字论点不能超过双层的范围。 在以下陈述中 ,数值 的论证比 bigint 的范围多出1倍。

DECLARE @datetime2 AS DATETIME2;

SET @datetime2 = '2025-11-01 01:01:01.1111111';

SELECT DATEADD(nanosecond, 9223372036854775808, @datetime2);

SELECT DATEADD(nanosecond, -9223372036854775809, @datetime2);

GO

这些语句都返回以下错误消息:

Msg 8115, Level 16, State 2, Line 3

Arithmetic overflow error converting expression to data type bigint.

date 参数

DATEADD不接受日期参数递增到其数据类型范围之外的值。 在以下语句中,与 date 值相加的 number 值超出了 date 数据类型的范围 。

SELECT DATEADD(year, 2147483647, '20240731');

SELECT DATEADD(year, -2147483647, '20240731');

DATEADD 返回以下错误消息:

Msg 517, Level 16, State 1

Line 1 Adding a value to a 'datetime' column caused overflow.

返回 smalldatetime 日期和秒或小数秒日期部分的值

smalldatetime 值的秒数部分始终为 00。 以下原则适用于 smalldatetime date 值:

对于日期部分second,以及介于 -30 和 +29 之间的数字值,DATEADD不进行更改。

,以及second值,从一分钟开始执行其加法。

对于日期部分millisecond和介于 -30001 和 +29998 之间的数字值,DATEADD不进行更改。

对于日期部分millisecond和小于 -30001 或大于 +29998 的数字值,DATEADD从一分钟开始执行其添加。

Remarks

在以下子句中使用 DATEADD:

GROUP BY

HAVING

ORDER BY

SELECT

WHERE

秒的小数部分精度

DATEADD不允许添加或microsecondnanosecond数据类型 smalldatetime、date 和 datetime。

毫秒的刻度为 3(.123),微秒的刻度为 6(.123456),纳米秒的刻度为 9(.123456789)。 时间、datetime2 和 datetimeoffset 数据类型的最大刻度为 7 ()。 .1234567

,nanosecond必须为 100,才能在日期增加的小数秒之前。 介于 1 和 49 之间的数字 向下舍入到 0,数字从 50 到 99 舍入到 100。

这些语句添加日期部分,millisecondmicrosecond或nanosecond。

DECLARE @datetime2 AS 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 不允许添加时区偏移量。

Examples

A. 以 1 为增量递增 datepart

以下每条语句以 1 为增量递增 datepart :

DECLARE @datetime2 AS 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. 在一个语句中递增多个 日期部分 级别

以下每个语句按足够大的 number 逐量增加 datepart,该 number 还应足以增加 date 的下一个更高的 datepart :

DECLARE @datetime2 AS 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 AS INT = 365,

@datetime AS 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

此示例指定 SYSDATETIME 为 date 。 返回的确切值取决于语句执行的日期和时间:

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)算术运算符(-)和标量系统函数()作为数字/。

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

相关内容

CAST 和 CONVERT (Transact-SQL)

相关推荐