返回指定的 startdate 和 enddate 之间所跨的指定datepart 边界的计数(带符号的整数)。
语法DATEDIFF ( datepart , startdate , enddate )参数
- datepart
是指定所跨边界类型的 startdate 和 enddate 的一部分。下表列出了所有有效的 datepart 参数。 用户定义的变量等效项是无效的。
datepart 缩写 year
yy, yyyy
quarter
qq, q
month
mm, m
dayofyear
dy, y
day
dd, d
week
wk, ww
hour
hh
minute
mi, n
second
ss, s
millisecond
ms
microsecond
mcs
nanosecond
ns
- startdate
是一个表达式,可以解析为time、date、smalldatetime、datetime、datetime2或 datetimeoffset 值。date可以是表达式、列表达式、用户定义的变量或字符串文字。从 enddate 减去startdate。
为避免不确定性,请使用四位数年份。 有关两位数年份的信息,请参阅twodigit year cutoff 选项。
- enddate
请参阅 startdate。
int
返回值如果返回值超出 int 的范围(-2,147,483,648 到+2,147,483,647),则会返回一个错误。 对于millisecond,startdate 与 enddate之间的最大差值为 24 天 20 小时 31 分钟 23.647 秒。 对于second,最大差值为 68 年。
如果为 startdate 和 enddate 都只指定了时间值,并且datepart 不是时间 datepart,则会返回 0。
在计算返回值时不使用 startdate 或 endate 的时区偏移量部分。
由于 smalldatetime 仅精确到分钟,因此将 smalldatetime值用作 startdate 或 enddate 时,返回值中的秒和毫秒将始终设置为 0。
如果只为某个日期数据类型的变量指定时间值,则所缺日期部分的值将设置为默认值:1900-01-01。如果只为某个时间或日期数据类型的变量指定日期值,则所缺时间部分的值将设置为默认值:00:00:00。 如果startdate 和 enddate中有一个只含时间部分,另一个只含日期部分,则所缺时间和日期部分将设置为各自的默认值。
如果 startdate 和 enddate属于不同的日期数据类型,并且其中一个的时间部分或秒的小数部分精度比另一个高,则另一个的所缺部分将设置为 0。
日期部分边界
以下语句具有相同的 startdate 和相同的 endate。这些日期是相邻的,在时间上相差 .0000001 秒。 每个语句中 startdate 与endate 之间的差跨其 datepart 的一个日历或时间边界。 每个语句都返回1。如果本例使用不同的年份且 startdate 和 endate 都在相同的日历周内,则week 的返回值将为 0。
SELECT DATEDIFF(year, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(quarter, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(month, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(dayofyear, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(day, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(week, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(hour, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(minute, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(second, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(millisecond, '2005-12-3123:59:59.9999999'
, '2006-01-01 00:00:00.0000000');
DATEDIFF 可用在选择列表、WHERE、HAVING、GROUP BY 和 ORDER BY 子句中。
示例以下示例使用不同类型的表达式作为 startdate 和 enddate形参的实参。
A. 为 startdate 和 enddate 指定列
下例计算一个表的两列中的日期之间所跨越的日边界数。
CREATE TABLE dbo.Duration ( startDate datetime2 ,endDate datetime2 )INSERT INTO dbo.Duration(startDate,endDate) VALUES('2007-05-06 12:10:09','2007-05-07 12:10:09')SELECT DATEDIFF(day,startDate,endDate) AS 'Duration'FROM dbo.Duration;-- Returns: 1
B. 为 startdate 和 enddate 指定用户定义的变量
下例使用用户定义的变量作为 startdate 和 enddate 的参数。
DECLARE @startdate datetime2 = '2007-05-05 12:10:09.3312722';DECLARE @enddate datetime2 = '2007-05-04 12:10:09.3312722'; SELECT DATEDIFF(day, @startdate, @enddate);
C. 为 startdate 和 enddate 指定标量系统函数
下例使用标量系统函数作为 startdate 和 enddate 的参数。
SELECT DATEDI FF(millisecond, GETDATE(), SYSDATETIME());
D. 为 startdate 和 enddate 指定标量子查询和标量函数
下例使用标量子查询和标量函数作为 startdate 和 enddate 的参数。
USE AdventureWorks;GOSELECT DATEDIFF(day,(SELECT MIN(OrderDate) FROM Sales.SalesOrderHeader), (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader));
E. 为 startdate 和 enddate 指定常量
下例使用字符常量作为 startdate 和 enddate 的参数。
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635' , '2007-05-08 09:53:01.0376635');
F. 为 enddate 指定数值表达式和标量系统函数
下例使用数值表达式 (GETDATE ()+ 1)
和标量系统函数GETDATE
与 SYSDATETIME
作为 enddate的参数。
注意: |
---|
SYSDATETIME、SYSUTCDATETIME 和 SYSDATETIMEOFFSET 不能作为算术表达式的一部分。 |
USE AdventureWorks;GOSELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', GETDATE()+ 1) AS NumberOfDaysFROM Sales.SalesOrderHeader;GOUSE AdventureWorks;GOSELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', DATEADD(day,1,SYSDATETIME())) AS NumberOfDaysFROM Sales.SalesOrderHeader;GO
G. 为 startdate 指定排名函数
下例使用排名函数作为 startdate 的参数。
USE AdventureWorks;GO
SELECT c.FirstName, c.LastName
,DATEDIFF(day,ROW_NUMBER() OVER (ORDER BY
a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson s
INNER JOINPerson.Contact c
ON s.SalesPersonID = c.ContactID
INNER JOINPerson.Address a
ON a.AddressID = c.ContactID
WHERE TerritoryID IS NOT NULL
AND SalesYTD<> 0;
H. 为 startdate 指定聚合开窗函数
下例使用聚合开窗函数作为 startdate 的参数。
USE AdventureWorks;GOSELECT soh.SalesOrderID, sod.ProductID, sod.OrderQty,soh.OrderDate ,DATEDIFF(day,MIN(soh.OrderDate) OVER(PARTITION BY soh.SalesOrderID),SYSDATETIME() ) AS 'Total'FROM Sales.SalesOrderDetail sod INNER JOIN Sales.SalesOrderHeader soh ON sod.SalesOrderID = soh.SalesOrderIDWHERE soh.SalesOrderID IN(43659,58918);GO