tsql: How to retrieve the last date of each month between given date range

前端 未结 9 1785
深忆病人
深忆病人 2020-12-06 22:00

I have two date for example 08/08/2013 and 11/11/2013 and I need last date of each month starting from August to November in a table so that i can iterate over the table to

相关标签:
9条回答
  • 2020-12-06 22:21

    I've created a table variable, filled it with all days between @startDate and @endDate and searched for max date in the month.

    declare @tmpTable table (dates date)
    declare @startDate date = '08/08/2013'
    declare @endDate date = '11/11/2013'
    
    while @startDate <= @endDate
    begin
        insert into @tmpTable (dates) values (@startDate)
        set @startDate = DATEADD(DAY, 1, @startDate)
    end
    
    select max(dates) as [Last day] from @tmpTable as o
    group by datepart(YEAR, dates), datepart(MONTH, dates)
    

    Results:

    Last day
    2013-08-31
    2013-09-30
    2013-10-31
    2013-11-11
    

    To also get last day of November this can be used before loop:

    set @endDate = DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, @endDate) + 1, 0))
    
    0 讨论(0)
  • 2020-12-06 22:30

    You can use a recursive CTE to do this, note the MAXRECURSION OPTION prevents an infinite loop:

    DECLARE @StartDate DATE = '2013-08-08'
    DECLARE @EndDate DATE = '2013-11-11'
    
    ;WITH dateCTE
    AS
    (
        SELECT CAST(DATEADD(M, 1,DATEADD(d, DAY(@StartDate) * -1, @StartDate)) AS DATE) EndOFMonth
        UNION ALL 
        SELECT CAST(DATEADD(M, 2,DATEADD(d, DAY(EndOFMonth) * -1, EndOFMonth)) AS DATE) 
        FROM dateCTE
        WHERE EndOFMonth < DATEADD(d, DAY(@EndDate) * -1, @EndDate)
    
    )
    SELECT *
    FROM dateCTE
    OPTION (MAXRECURSION 30);
    

    This returns

    EndOFMonth
    ----------
    2013-08-31
    2013-09-30
    2013-10-31
    
    0 讨论(0)
  • 2020-12-06 22:30

    Although the question is about the last day which @bummi has already answered.

    But here is the solution for the first date which might be helpful for someone.

    Get the first dates of all the months in-between the @FromDate and @ToDate.

    DECLARE @FromDate DATETIME = '2019-08-13'
    DECLARE @ToDate DATETIME = '2019-11-25'
    
    ;WITH CTE
    AS 
    (
        SELECT DATEADD(DAY, -(DAY(@FromDate) - 1), @FromDate) AS FirstDateOfMonth
    
        UNION ALL
    
        SELECT DATEADD(MONTH, 1, FirstDateOfMonth)
        FROM CTE
        WHERE FirstDateOfMonth < DATEADD(DAY, -(DAY(@ToDate) - 1), @ToDate)
    )
    SELECT * FROM CTE
    

    Here is the result

    --Result
    2019-08-01 00:00:00.000
    2019-09-01 00:00:00.000
    2019-10-01 00:00:00.000
    2019-11-01 00:00:00.000
    
    0 讨论(0)
提交回复
热议问题