使用包含2个date参数的date填充临时表的最简单的方法

使用包含date参数和date参数的date填充临时表的最简单方法是什么? 我只需要在月份的第一天。

所以例如,如果@StartDate ='2011-01-01'和@EndDate ='2011-08-01'

然后我想要这个返回在表中

2011-01-01 2011-02-01 2011-03-01 2011-04-01 2011-05-01 2011-06-01 2011-07-01 2011-08-01 

即使@StartDate不是本月的第一个,这也是有效的。 我假设,如果这不是一个月的开始,你想从下个月的第一个开始。 否则删除+1

 ;WITH cte AS ( SELECT CASE WHEN DATEPART(Day,@StartDate) = 1 THEN @StartDate ELSE DATEADD(Month,DATEDIFF(Month,0,@StartDate)+1,0) END AS myDate UNION ALL SELECT DATEADD(Month,1,myDate) FROM cte WHERE DATEADD(Month,1,myDate) <= @EndDate ) SELECT myDate FROM cte OPTION (MAXRECURSION 0) 
 declare @StartDate date = '2014-01-01'; declare @EndDate date = '2014-05-05'; ;WITH cte AS ( SELECT @StartDate AS myDate UNION ALL SELECT DATEADD(day,1,myDate) as myDate FROM cte WHERE DATEADD(day,1,myDate) <= @EndDate ) SELECT myDate FROM cte OPTION (MAXRECURSION 0) 
 declare @StartDate datetime declare @EndDate datetime select @StartDate = '2011-01-01' , @EndDate = '2011-08-01' select @StartDate= @StartDate-(DATEPART(DD,@StartDate)-1) declare @temp table ( TheDate datetime ) while (@StartDate<=@EndDate) begin insert into @temp values (@StartDate ) select @StartDate=DATEADD(MM,1,@StartDate) end select * from @temp 

即使@StartDate不是当月的第一天,也可以返回到StartDate的月份的开始date

这在SQL 2008 R2中进行了testing

 Declare @StartDate datetime = '2015-03-01' Declare @EndDate datetime = '2015-03-31' declare @temp Table ( DayDate datetime ); WHILE @StartDate <= @EndDate begin INSERT INTO @temp (DayDate) VALUES (@StartDate); SET @StartDate = Dateadd(Day,1, @StartDate); end ; select * from @temp 

结果:

 DayDate ----------------------- 2015-03-01 00:00:00.000 2015-03-02 00:00:00.000 2015-03-03 00:00:00.000 2015-03-04 00:00:00.000 ... 

解:

 DECLARE @StartDate DATETIME ,@EndDate DATETIME; SELECT @StartDate = '20110105' ,@EndDate = '20110815'; SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, DATEADD(MONTH, v.number, @StartDate)), 0) AS FirstDay --or Andriy M suggestion: --SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, @StartDate) + v.number, 0) AS FirstDay INTO #Results FROM master.dbo.spt_values v WHERE v.type = 'P' AND DATEDIFF(MONTH, @StartDate, @EndDate) >= v.number; SELECT * FROM #Results; DROP TABLE #Results; 

结果:

 FirstDay ----------------------- 2011-01-01 00:00:00.000 2011-02-01 00:00:00.000 2011-03-01 00:00:00.000 2011-04-01 00:00:00.000 2011-05-01 00:00:00.000 2011-06-01 00:00:00.000 2011-07-01 00:00:00.000 2011-08-01 00:00:00.000 

有趣的是,根据本文创build枚举数据会更快。

 DECLARE @StartDate DATE = '10001201'; DECLARE @EndDate DATE = '20000101'; DECLARE @dim TABLE ([date] DATE) INSERT @dim([date]) SELECT d FROM ( SELECT d = DATEADD(DAY, rn - 1, @StartDate) FROM ( SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate)) rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id]) FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2 ORDER BY s1.[object_id] ) AS x ) AS y; 

在我的机器上,大date范围的速度快了大约60%。 recursion方法可以在3秒左右的时间内填充2000年的数据,而且看起来好多了,所以我不推荐这种方法来增加日子。

更正空date:

 IF OBJECT_ID('tempdb..#dim') IS NOT NULL DROP TABLE #dim CREATE TABLE #dim ([date] DATE) if not @Begin_Date is null and not @End_Date is null begin INSERT #dim([date]) SELECT d FROM( SELECT d = DATEADD(DAY, rn - 1, @Begin_Date) FROM ( SELECT TOP (DATEDIFF(DAY, @Begin_Date, @End_Date)) rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id]) FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2 ORDER BY s1.[object_id] ) AS x ) AS y; end