tsql: How to retrieve the last date of each month

2020-02-01 12:35发布

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 pick those dates individually.

I know how to pick last date for any month but i am stucked with a date range.

kindly help, it will be highly appreciated.

Note : I am using Sql 2008 and date rang could be 1 month , 2 month or 6 month or a year or max too..

9条回答
神经病院院长
2楼-- · 2020-02-01 12:52

try this the last row(where) is optional for date filtering

declare @table table  
(  
thisdate date  
)


insert into @table values ('12/01/2013'),('05/06/2013'),('04/29/2013'),('02/20/2013')
select *,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,thisdate)+1,0))
LastDay from @table
where thisdate between 'givendate' and 'givendate'

The Example Below is for all dates

thisdate    lastday
2013-12-01  2013-12-31 23:59:59.000
2013-05-06  2013-05-31 23:59:59.000
2013-04-29  2013-04-30 23:59:59.000
2013-02-20  2013-02-28 23:59:59.000
查看更多
Emotional °昔
3楼-- · 2020-02-01 12:53

Following script demonstrates the script to find last day of previous, current and next month.

----Last Day of Previous Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
LastDay_PreviousMonth
----Last Day of Current Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
LastDay_CurrentMonth
----Last Day of Next Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0))
LastDay_NextMonth

If you want to find last day of month of any day specified use following script.

--Last Day of Any Month and Year
DECLARE @dtDate DATETIME
SET @dtDate = '8/18/2007'
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@dtDate)+1,0))
LastDay_AnyMonth
ResultSet:
LastDay_AnyMonth

Source - SQL Server Central.

查看更多
相关推荐>>
4楼-- · 2020-02-01 12:53

No need to use a common table expression or anything like that - this simple query will do it:

SELECT  DATEADD(d, -1, DATEADD(mm, DATEDIFF(m, 0, DATEADD(m, number, '2013-08-08')) + 1, 0)) AS EndOfMonth
FROM    master.dbo.spt_values
WHERE   'P' = type
        AND DATEADD(m, number, '2013-08-08') < '2013-11-11';
查看更多
Animai°情兽
5楼-- · 2020-02-01 12:54
DECLARE @tmpTable table (LastDates DATE);
DECLARE @startDate DATE = '01/01/2012'; --1 Jan 2012
DECLARE @endDate DATE = '05/31/2012';   --31 May 2012
DECLARE @tmpEndDate DATE;

SET @startDate = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@startDate)+1,1));
SET @tmpEndDate = DATEADD(DAY, 1, @endDate);

WHILE (@startDate <= @tmpEndDate)
BEGIN   
    INSERT INTO @tmpTable (LastDates) values (DATEADD(DAY, -1, @startDate));
    SET @startDate = DATEADD(MONTH, 1, @startDate);
END

SELECT [LastDates] FROM @tmpTable;

Output:

Example: 1

@startDate DATE = '01/01/2012'; --1 Jan 2012
@endDate DATE = '05/31/2012';   --31 May 2012

LastDates
----------
2012-01-31
2012-02-29
2012-03-31
2012-04-30
2012-05-31

Example: 2

@startDate DATE = '11/01/2011'; --1 Nov 2011
@endDate DATE = '03/13/2012';   --13 Mar 2012

LastDates
----------
2011-11-30
2011-12-31
2012-01-31
2012-02-29
查看更多
时光不老,我们不散
6楼-- · 2020-02-01 12:55

You can use CTE for getting all last days of the month within the defined range

Declare @Start datetime
Declare @End datetime

Select @Start = '20130808'
Select @End = '20131111'
;With CTE as
(
Select @Start  as Date,Case When DatePart(mm,@Start)<>DatePart(mm,@Start+1) then 1 else 0 end as [Last]
UNION ALL
Select Date+1,Case When DatePart(mm,Date+1)<>DatePart(mm,Date+2) then 1 else 0 end from CTE
Where Date<@End
)

Select * from CTE
where [Last]=1   OPTION ( MAXRECURSION 0 )
查看更多
我命由我不由天
7楼-- · 2020-02-01 12:58

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
查看更多
登录 后发表回答