DATEADD函数问题

时间:2017-01-05 16:40:50

标签: sql sql-server date dateadd

我根据日期和年份在SQL中进行了大量计算。当我将日期添加到日期时,它不会根据日期添加,它主要增加3个月(这就是该功能的功能)。

例如SELECT DATEADD(month, 4, '2016-10-25')。这取决于我期待的是2017-02-25

但是当我这样做时DATEADD(month, 4, '2016-10-30')。它取得了2017-28。这不是我所期待的。我知道这个功能只会增加几个月并将它带到那个月的最后一天。

在这种情况下,如果我想看到2016-02-30的输出是可能的,因为我知道日期不存在。或者我们是否有可能将其编程为2017-03-01而不是2017-02-28。 (这在闰年期间成为一个更大的问题,因为我们确实有2月29日)

我非常感谢您对此的回应。谢谢。

3 个答案:

答案 0 :(得分:1)

您可以根据要添加的月份的天数进行一些计算,并添加目标月份没有多天的额外天数:

CREATE TABLE #dates ( val DATE );

INSERT  INTO #dates
        ( val )
VALUES  ( '20160131' ),
        ( '20160130' ),
        ( '20160129' );

SELECT  val ,
        DATEADD(MONTH, 1, val) StandardMonthAdd ,
        CASE WHEN DATEPART(DAY, val) != DATEPART(DAY, DATEADD(MONTH, 1, val))
             THEN DATEADD(DAY,
                          DATEPART(DAY, val) - DATEPART(DAY,
                                                        DATEADD(MONTH, 1, val)),
                          DATEADD(MONTH, 1, val))
             ELSE DATEADD(MONTH, 1, val)
        END CalculatedMonthAdd
FROM    #dates;

DROP TABLE #dates;

<强>产地:

val         StandardMonthAdd    CalculatedMonthAdd
2016-01-31  2016-02-29          2016-03-02
2016-01-30  2016-02-29          2016-03-01
2016-01-29  2016-02-29          2016-02-29

这假设对于记录1,因为2月没有31天想要添加2天,而对于记录2,则添加1天。

答案 1 :(得分:0)

显然,没有合理的软件系统会产生2017-02-30。这太过要求了。

如果你想去下个月而不是去月的最后一天,你可以这样做:

select (case when day(d) <= 28 or day(d) = day(dateadd(month, 4, d))
             then dateadd(month, 4, d)
             else dateadd(month, 5, dateadd(day, 1 - day(d), day)
        end)

这说:

  1. 只要四个月后的一天与现在的一天相同,加上4个月就可以了。
  2. 否则,请在月末5个月前到达。

答案 2 :(得分:0)

尝试2月31日等等

    -- ================================================
-- Template generated from Template Explorer using:
-- Create Scalar Function (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date, ,>
-- Description: <Description, ,>
-- =============================================
create FUNCTION fn_Add_Full_Months
(
    -- Add the parameters for the function here
    @DATE as datetime,
    @MONTHADD as int
)
RETURNS nvarchar(10)
AS
BEGIN
    -- Declare the return variable here

    DECLARE @DAYS as int = DAY(@DATE);
    DECLARE @MONTHS as int = MONTH(@DATE);
    DECLARE @YEARS as int = YEAR(@DATE);

    DECLARE @TRIAL as int = @YEARS*12 +  @MONTHS - 1 + @MONTHADD;

    RETURN CAST(@TRIAL / 12 AS nvarchar(4)) + '-' + 
                RIGHT('0' + CAST(@TRIAL % 12 + 1 AS nvarchar(4)), 2)  + '-' + 
                RIGHT('0' + CAST(@DAYS  AS nvarchar(4)), 2);

END
GO

然后

select dbo.fn_Add_Full_Months('19960131', 1);