计算SQL中两个日期之间的完整月数

osc*_*kuo 50 sql sql-server

我需要计算SQL中的FULL月数,即

  • 2009-04-16至2009-05-15 => 0整月
  • 2009-04-16至2009-05-16 => 1个月
  • 2009-04-16至2009-06-16 => 2个月

我试图使用DATEDIFF,即

SELECT DATEDIFF(MONTH, '2009-04-16', '2009-05-15')
Run Code Online (Sandbox Code Playgroud)

但不是给我两个日期之间的完整月份,而是给出了月份部分的差异,即

1
Run Code Online (Sandbox Code Playgroud)

有谁知道如何计算SQL Server中的整月数?

Joe*_*vis 50

原帖有一些错误......所以我重新编写并将其打包为UDF.

CREATE FUNCTION FullMonthsSeparation 
(
    @DateA DATETIME,
    @DateB DATETIME
)
RETURNS INT
AS
BEGIN
    DECLARE @Result INT

    DECLARE @DateX DATETIME
    DECLARE @DateY DATETIME

    IF(@DateA < @DateB)
    BEGIN
        SET @DateX = @DateA
        SET @DateY = @DateB
    END
    ELSE
    BEGIN
        SET @DateX = @DateB
        SET @DateY = @DateA
    END

    SET @Result = (
                    SELECT 
                    CASE 
                        WHEN DATEPART(DAY, @DateX) > DATEPART(DAY, @DateY)
                        THEN DATEDIFF(MONTH, @DateX, @DateY) - 1
                        ELSE DATEDIFF(MONTH, @DateX, @DateY)
                    END
                    )

    RETURN @Result
END
GO

SELECT dbo.FullMonthsSeparation('2009-04-16', '2009-05-15') as MonthSep -- =0
SELECT dbo.FullMonthsSeparation('2009-04-16', '2009-05-16') as MonthSep -- =1
SELECT dbo.FullMonthsSeparation('2009-04-16', '2009-06-16') as MonthSep -- =2
Run Code Online (Sandbox Code Playgroud)

  • 是的,我知道这个答案已经超过5年了,但我在谷歌搜索时遇到过它.这只有一个问题,它在比较一个月的结束日时会下降.FullMonthsSeparation('2012-12-31','2013-02-28')返回1,而不是2. (3认同)
  • 这在 2019-01-31 和 2019-02-28 之间得到错误的结果。答案应该是 1。但是这个函数返回 0 (3认同)
  • 这就是OP要求的行为。 (2认同)

小智 6

select case when DATEPART(D,End_dATE) >=DATEPART(D,sTAR_dATE) 
THEN ( case when DATEPART(M,End_dATE) = DATEPART(M,sTAR_dATE) AND DATEPART(YYYY,End_dATE) = DATEPART(YYYY,sTAR_dATE) 
        THEN 0 ELSE DATEDIFF(M,sTAR_dATE,End_dATE)END )
ELSE DATEDIFF(M,sTAR_dATE,End_dATE)-1 END
Run Code Online (Sandbox Code Playgroud)


MyI*_*hin 5

你对一个月的定义是什么?从技术上讲,一个月可以是 28、29、30 或 31 天,具体取决于月份和闰年。

似乎您正在考虑将一个月设为 30 天,因为在您的示例中您忽略了 May 有 31 天,那么为什么不执行以下操作呢?

SELECT DATEDIFF(DAY, '2009-04-16', '2009-05-15')/30
    , DATEDIFF(DAY, '2009-04-16', '2009-05-16')/30
    , DATEDIFF(DAY, '2009-04-16', '2009-06-16')/30
Run Code Online (Sandbox Code Playgroud)

  • 我认为OP想要回答的问题是:“在第一个日期通过第二个日期之前,我可以将第一个日期的‘月份’增加多少次?” (适当处理年份) (2认同)

Ste*_*lke 5

这仅适用于ORACLE,不适用于 SQL-Server:

months_between(to_date ('2009/05/15', 'yyyy/mm/dd'), 
               to_date ('2009/04/16', 'yyyy/mm/dd'))
Run Code Online (Sandbox Code Playgroud)

整月:

round(months_between(to_date ('2009/05/15', 'yyyy/mm/dd'), 
                     to_date ('2009/04/16', 'yyyy/mm/dd')))
Run Code Online (Sandbox Code Playgroud)

可以在Oracle 8i 及以上版本中使用。


小智 5

dateadd函数可用于偏移到月初。如果endDate的天部分少于startDate,则它将被推到前一个月,因此datediff将给出正确的月数。

DATEDIFF(MONTH, DATEADD(DAY,-DAY(startDate)+1,startDate),DATEADD(DAY,-DAY(startDate)+1,endDate))
Run Code Online (Sandbox Code Playgroud)