获取SQL Server中两个月之间的月末日期列表

时间:2017-05-25 00:12:24

标签: sql-server

这类似于mySQL问题,除了我只想要月末日期:Get a list of dates between two dates

我希望能够输入两个日期,例如:

SELECT EndOfMonth('1/1/2015', '1/1/2017');

返回的结果应该是

EndOfMonth
1/31/2015
2/28/2015
3/31/2015
.
.
.
10/31/2016
11/30/2016
12/31/2016

我使用的SQL Server版本是2008,所以我实际上无法访问EOMONTH()。

4 个答案:

答案 0 :(得分:3)

使用数字表可以让事情变得更轻松。如果您还没有数字表,可以使用以下sql创建一个(取自this SO post):

SELECT TOP 10000 IDENTITY(int,0,1) AS Number
INTO Tally
FROM sys.objects s1       
CROSS JOIN sys.objects s2 

ALTER TABLE Tally ADD CONSTRAINT PK_Tally PRIMARY KEY CLUSTERED (Number)

要详细了解数字表及其使用方法,请阅读Jeff Moden的The "Numbers" or "Tally" Table: What it is and how it replaces a loop文章。

使用EOMONTH内置功能后,使用数字表对2012或更高版本来说相当容易:

DECLARE @Start date = '2015-01-01', @End date = '2017-01-01'

SELECT EOMONTH(DATEADD(MONTH, Number, @Start))
FROM Tally
WHERE Number < DATEDIFF(MONTH, @Start, @End)

对于早期版本,您可以使用DATEADDDATEDIFF来获取上个月的最后一天,然后只需添加一个月:

SELECT DATEADD(DAY, -DATEPART(DAY, @Start), (DATEADD(MONTH, Number+1, @Start)))
FROM Tally
WHERE Number < DATEDIFF(MONTH, @Start, @End)

See a live demo on rextester

答案 1 :(得分:2)

您可以使用Common Table表达式(CTE)轻松实现此目的。

--Declaration of start date and end date
declare @StartDate datetime='2017-01-01', @endDate datetime='2017-12-01'

-- Expression
;WITH monthcte
     AS (SELECT EOMONTH(@StartDate) AS dates
         UNION ALL
         SELECT DATEADD(month, 1, dates) AS dates
         FROM   monthcte
         WHERE  dates <@endDate     
         )

-- Select query over expression
SELECT  EOMONTH(dates) AS EndOfMonth
FROM   monthcte
Order by EndOfMonth

答案 2 :(得分:0)

如果您无法使用EOMonth,可以按如下方式生成:

declare @d1 date = '1/1/2015'
declare @d2 date = '1/1/2017'

select top (datediff(MONTH,@d1,@d2)+1) Dates = DateAdd(day,-1, Dateadd(M,Row_number() over(order by (select null)), @d1)) from
    master..spt_values n1, master..spt_values n2

如果您的SQL Server版本中有EoMonth,那么您可以尝试如下:

select top (datediff(MONTH,@d1,@d2)+1) Dates = EoMonth(Dateadd(M,Row_number() over(order by (select null))-1, @d1)) from
    master..spt_values n1, master..spt_values n2

答案 3 :(得分:0)

月份列表:

DECLARE @StartDate datetime
DECLARE @EndDate datetime
set @StartDate = '01/01/2015'
set @EndDate = '01/01/2017'

;WITH cte1 (S) AS (
SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (S)
),
cte2 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte1 AS cte2),
cte3 (S) AS (SELECT 1 FROM cte1 AS cte1 CROSS JOIN cte2 AS cte2)

select distinct cast(result as date) result from
(SELECT TOP (DATEDIFF(day, @StartDate, @EndDate) + 1)
        result = DATEADD(day, ROW_NUMBER() OVER(ORDER BY S) - 1, @StartDate)
FROM cte3) as res