简体   繁体   English

在 SQL Server 中使用 DATEDIFF 的最准确方法是什么?

[英]What is the most accurate way of using DATEDIFF in SQL Server?

I have two computed columns (MonthsInService and YearsInService) with the following expressions.我有两个带有以下表达式的计算列(MonthsInService 和 YearsInService)。

MonthsInService = (datediff(month,[DateEngaged],getdate())) MonthsInService = (datediff(month,[DateEngaged],getdate()))

YearsInService = (datediff(month,[DateEngaged],getdate())/(12)) YearsInService = (datediff(month,[DateEngaged],getdate())/(12))

Now if for example DateEngaged = 2012-April-09 and getdate() is 2013-April-08, MonthsInService returns 12 and YearsInService is 1.现在,如果 DateEngaged = 2012-April-09 并且 getdate() 为 2013-April-08,则 MonthsInService 返回 12 并且 YearsInService 为 1。

My application requires that YearsInService be Zero since there is still one day to go before the employees first Anniversary.我的应用程序要求 YearsInService 为零,因为距离员工一周年还有一天。

Am not even sure how to best handle the MonthsInService column since months have varying number of days.我什至不确定如何最好地处理 MonthsInService 列,因为月份有不同的天数。

Unfortunately, DATEDIFF computes the number of transitions of the element, rather than the usual, human intuition of the difference between two dates (eg DATEDIFF(year,'20121231','20130101') is 1, even though not many people would say that there's a difference of a year). 不幸的是, DATEDIFF计算元素的转换次数,而不是通常的人类对两个日期之间差异的直觉(例如DATEDIFF(year,'20121231','20130101')是1,尽管没有多少人会说有一年的差异)。

The solution I'd use is a bit repetitive, but doesn't need a separate function, and always gets eg leap years correct: 我使用的解决方案有点重复,但不需要单独的功能,并且总是得到例如闰年:

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

Produces: 生产:

DateEngaged             MonthsInService YearsInService
----------------------- --------------- --------------
2012-04-09 00:00:00.000 11              0
2012-04-08 00:00:00.000 12              1

It works by asking "If we take the naive answer produced by DATEDIFF , does it given an answer that's too high by 1?" 它的工作原理是“如果我们采用DATEDIFF产生的天真答案,它是否给出了一个太高的答案?” - and if so, we just subtract one from the answer it gives. - 如果是这样,我们只从它给出的答案中减去一个。 DATEDIFF should only ever be over by 1. DATEDIFF应该只能超过1。

Via using day you can reach the result: 通过使用day您可以达到结果:

select 
datediff(month,'2012-April-09','2013-April-08') MonthsInService
,datediff(day,'2012-April-09','2013-April-08')/365 YearsInService

Output : 输出

12  0  

or use function for maximum precision: 或使用函数以获得最大精度:

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

For months calculation you can refer here: Calculating number of full months between two dates in SQL 对于月计算,您可以在此处参考: 计算SQL中两个日期之间的完整月数

DATEDIFF(DAY, CONVERT(date, dtmDOB), DATEDIFF(天,转换(日期,dtmDOB),
CONVERT(date, GETDATE()))*(12.0/365.25)),1))转换(日期,GETDATE()))*(12.0/365.25)),1))
AS TotalMonths, AS TotalMonths,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SQL 服务器:DATEDIFF 不准确 - SQL Server : DATEDIFF not accurate 服务器总内存-通过SQL Server获取内存的最准确方法是什么? - Total server memory - what is the most accurate way to get it through SQL Server? 在SQL Server中使用DATEDIFF计算工作时间 - Calculate working hours using DATEDIFF in SQL Server 如何使用 datediff 优化 sql 服务器查询 - How to optimize sql server query by using datediff SQL Server-将DATEDIFF与子查询列一起使用 - SQL SERVER - Using DATEDIFF with subquery column 使用.NET将单个记录写入MS SQL 2008 Server的最有效方法是什么? - What's the most efficient way to write a single record to an MS SQL 2008 Server using .NET? 使用 SSIS 将 csv 文件导入 SQL 服务器时,从字符串中删除空格的最有效方法是什么? - What is the most efficient way to remove a space from a string when importing a csv file to SQL Server using SSIS? 为什么使用周数时,SQL Server dateadd datediff的行为方式如此 - Why does SQL Server dateadd datediff behave behave this way when using weeks 什么是检查SQL Server中是否存在触发器的最便携方法? - What is the most portable way to check whether a trigger exists in SQL Server? 将UniDataSet复制到SQL Server的最有效方法是什么? - What is the most efficient way to copy UniDataSet to SQL Server?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM