2017-05-25 54 views
0

这类似于这个MySQL的问题除了我只想一个月中日期的结尾:Get a list of dates between two dates得到两月之间的月日结束的列表中的SQL Server

我希望能够进入两个日期,东西像:

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访问()。

+0

您使用的是哪个版本的sql server? –

回答

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) 

要了解更多有关数字表以及如何使用它,阅读杰夫MODEN的The "Numbers" or "Tally" Table: What it is and how it replaces a loop文章。

一旦你有一个数字表,它是用2012或更高版本相当容易,使用内置在功能上EOMONTH

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

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 

如果EOMONTH是在你的SQL Server版本可用,那么你可以按照以下尝试:

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 
+0

为什么downvote?你能发布原因吗? –

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 
2

您可以使用公用表表达式(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 
相关问题