簡體   English   中英

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

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM