2009-09-08 10 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) 

問題は、しかし、私はeggheadcafeのゲイル・エリクソン[MS]によってポストによると、100以上であることを再帰を設定する必要があるということです、これは現在サポートされていません。

実際に(一時的ではない)を作成しないで、テーブルに日付がちょうど入っていますが、これを行う方法はありますか?

私はSqlServer2005を使用しています。

+0

私がサポートしている最大レベルは2^15で修正覚えていれば再帰レベルが100よりも高い値に設定することが可能です。 – Faiz

答えて

6

あなた最良の選択肢は実際に日付の物理的な表を持つことです。長い期間でさえ多くのものがありませんし、一時テーブルや再帰的なcteからオンザフライで実現するよりもはるかに高速です。

+1

日付のテーブルを使用したくない場合は、中間の解決策です。数字の小さいテーブル(0から1000など)を使用し、 の選択キャスト(@minDateとdatetime)+ Val from tblNumbersここで、val <=(キャスト(日時として@minDate) - キャスト(日時として@maxDate)) (ValはtblNumberのINTフィールドで、値は0,1,2 ...) – mjv

+0

ありがとう、私物理的なテーブルと一緒に行くことにしましたが、ちょうど日付を格納する1つのカラムを持つテーブルを持つのは悪い考えです。 –

+2

悪い考えではありません。これは、プログラマーが持っている通常のアルゴリズム指向のやり方に反するものです。それだけです。実際には、0から1ミルまでの数字のテーブルを持つことをお勧めします。あなたのようなジョインやクエリーで使用することができます。 –

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

+0

@Faiz、私は好奇心が強いです。のcteソリューションの? –

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 - これは今日、タリーテーブルを含む3番目の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!同じ解決策を出す前にこれを見ていなかった。 –

関連する問題