2009-09-08 46 views
5

我需要創建一個返回連續日期表的函數。我會通過一個最短日期&。連續日期的返回臨時表

我希望它能夠被稱爲是這樣的:

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據對eggheadcafe後由蓋爾·埃裏克森[MS],目前暫不支持。

沒有創建一個真正的(不是臨時的)表中只有日期,有沒有辦法做到這一點?

我使用SQLServer2005的。

+0

它可能有遞歸級別設置爲大於100更高的價值。如果我記得正確支持的最大級別是2^15。 – Faiz 2009-09-08 18:02:29

回答

6

它可以永遠運行最好的選擇是實際上有一個物理日期表。即使很長時間也沒有那麼多,並且比從臨時表或遞歸類實時實現它們要快得多。

+1

一箇中間解決方案,如果你不希望有一個日期表是使用一個[小]的數字表(比如說從0到1000),並有類似 選擇投射(@minDate作爲日期時間)+ Val 從tblNumbers其中val <=(流延(如@minDate日期時間) - 鑄造(@maxDate作爲日期時間)) (假設的Val是在tblNumber的INT字段,具有值0,1,2 ...) – mjv 2009-09-08 18:15:59

+0

謝謝,我我們已經決定與物理表一起使用,但只有一列存儲只有日期的表格似乎不是個好主意。 – 2009-09-08 18:26:23

+2

不是一個壞主意。它違背了程序員正常的面向算法的思維方式,就是這樣。其實很多人建議有一個只有數字的桌子,從0到1密爾。或類似的,用於類似於你的連接和查詢。 – 2009-09-08 18:37:22

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後...添加輸入參數檢查,以確保,或者如果你傳遞向後日期

+0

循環將會變慢。 CTE將是更好的選擇 – Faiz 2009-09-08 18:14:19

+0

@Faiz,我很好奇你能不能展示如cte解決方案? – 2009-09-08 18:15:54

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) 

奇怪 - 這是今天第三個SO後,參與理貨表。一定是一些奇怪的太陽黑子活動正在進行。下面是linkes:

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?

+0

Doh!在制定相同的解決方案之前沒有看到這一點。 – 2009-09-08 18:52:10