返回连续日期的临时表

时间:2009-09-08 17:54:40

标签: sql sql-server sql-server-2005 tsql

我需要创建一个返回连续日期表的函数。我会通过一个min&最长日期。

我希望能够像这样调用它:

SELECT * FROM GetDates('01/01/2009', '12/31/2009')

我目前有一个存储过程执行此操作,但需求已更改,现在我需要包含从联合中返回的数据:

 with mycte as
(
     select cast(@minDate as datetime) DateValue
     union all
     select DateValue + 1
     from    mycte   
     where   DateValue + 1 <= @maxDate
 )
 select DateValue
 from    mycte
option (maxrecursion 1000)

然而,问题是我需要将递归设置为大于100.根据Gail Erickson [MS]在eggheadcafe上发布的帖子,目前不支持。

如果没有创建一个只包含日期的真实(非临时)表,有没有办法做到这一点?

我正在使用SqlServer2005。

3 个答案:

答案 0 :(得分:6)

您最好的选择是实际拥有一个物理日期表。即使很长一段时间也没有那么多,并且比从临时表或递归ctes中即时实现它们要快得多。

答案 1 :(得分:3)

如果您选择(或需要)使用临时表而不是永久表,则可以这样做:

CREATE FUNCTION dbo.DateList
 (
   @MinDate datetime
  ,@MaxDate datetime
 )
RETURNS TABLE
RETURN WITH
  Pass0 as (select 1 as C union all select 1), --2 rows
  Pass1 as (select 1 as C from Pass0 as A, Pass0 as B),--4 rows
  Pass2 as (select 1 as C from Pass1 as A, Pass1 as B),--16 rows
  Pass3 as (select 1 as C from Pass2 as A, Pass2 as B),--256 rows
  Pass4 as (select 1 as C from Pass3 as A, Pass3 as B),--65536 rows
  Tally as (select row_number() over(order by C) as Number from Pass4)
 select dateadd(dd, Number - 1, @MinDate) DateValue
 from Tally
 where Number < datediff(dd, @MindAte, @MaxDate) + 2

GO

测试电话:

DECLARE
  @MinDate datetime
 ,@MaxDate datetime

SET @MinDate = 'Jan 1, 2009'
SET @MaxDate = 'Dec 31, 2009'

SELECT *
 from dbo.DateList(@MinDate, @MaxDate)

Wierd - 这是今天涉及Tally牌桌的第三篇SO帖子。必须是一些奇怪的太阳黑子活动。以下是链接:

count number of rows that occur for each date in column date range.
What is the best way to create and populate a numbers table?

答案 2 :(得分:1)

类似的东西:

CREATE FUNCTION GetDates(@StartDate DateTime, @EndDate DateTime) 

RETURNS @Dates Table ( aDate DateTime Primary Key Not Null)
AS
BEGIN
 Declare @ThisDate DateTime Set @ThisDate = @StartDate  
 While @ThisDate < @EndDate begin      
      Insert @Dates (aDate) Values(@THisDate)      
      Set @ThisDate = @ThisDate + 1  
 End
RETURN 
END
GO

确保@EndDate在@startdate之后...添加输入参数检查以确保,或者如果你向后传递它可以永远运行