[英]What is the most accurate way of using DATEDIFF in SQL Server?
我有两个带有以下表达式的计算列(MonthsInService 和 YearsInService)。
MonthsInService = (datediff(month,[DateEngaged],getdate()))
YearsInService = (datediff(month,[DateEngaged],getdate())/(12))
现在,如果 DateEngaged = 2012-April-09 并且 getdate() 为 2013-April-08,则 MonthsInService 返回 12 并且 YearsInService 为 1。
我的应用程序要求 YearsInService 为零,因为距离员工一周年还有一天。
我什至不确定如何最好地处理 MonthsInService 列,因为月份有不同的天数。
不幸的是, DATEDIFF
计算元素的转换次数,而不是通常的人类对两个日期之间差异的直觉(例如DATEDIFF(year,'20121231','20130101')
是1,尽管没有多少人会说有一年的差异)。
我使用的解决方案有点重复,但不需要单独的功能,并且总是得到例如闰年:
declare @T table (
DateEngaged datetime not null,
MonthsInService as CASE
WHEN DATEADD(month,DATEDIFF(month,DateEngaged,GETDATE()),DateEngaged) > GETDATE()
THEN DATEDIFF(month,DateEngaged,GETDATE()) - 1
ELSE DATEDIFF(month,DateEngaged,GETDATE())
END,
YearsInService as CASE
WHEN DATEADD(year,DATEDIFF(year,DateEngaged,GETDATE()),DateEngaged) > GETDATE()
THEN DATEDIFF(year,DateEngaged,GETDATE()) - 1
ELSE DATEDIFF(year,DateEngaged,GETDATE())
END
)
insert into @T (DateEngaged) values ('20120409'),('20120408')
select * from @T
生产:
DateEngaged MonthsInService YearsInService
----------------------- --------------- --------------
2012-04-09 00:00:00.000 11 0
2012-04-08 00:00:00.000 12 1
它的工作原理是“如果我们采用DATEDIFF
产生的天真答案,它是否给出了一个太高的答案?” - 如果是这样,我们只从它给出的答案中减去一个。 DATEDIFF
应该只能超过1。
通过使用day
您可以达到结果:
select
datediff(month,'2012-April-09','2013-April-08') MonthsInService
,datediff(day,'2012-April-09','2013-April-08')/365 YearsInService
输出 :
12 0
或使用函数以获得最大精度:
CREATE FUNCTION [dbo].[getFullYears]
(
@dateX datetime,
@dateY datetime
)
RETURNS int
AS
BEGIN
DECLARE @y int
SET @y =DATEDIFF(year,@dateX,@dateY)
IF (@dateY < DATEADD(year, @y, @dateX)) SET @y = @y -1
RETURN @y
END
select dbo.getFullYears('2012-April-09','2013-April-09') --1
select dbo.getFullYears('2012-April-09','2013-April-08') --0
对于月计算,您可以在此处参考: 计算SQL中两个日期之间的完整月数
DATEDIFF(天,转换(日期,dtmDOB),
转换(日期,GETDATE()))*(12.0/365.25)),1))
AS TotalMonths,
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.