2009-09-08 2 views
5

연속 된 날짜의 테이블을 반환하는 함수를 만들어야합니다. 나는 최소 & 최대 날짜를 전달할 것이다. 나는 그것이 수 있기를 기대연속 된 임시 테이블 반환

은 다음과 같이 호출 할 수 :

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

나는 현재이 작업을 수행 proc 디렉토리에 저장,하지만 요구 사항이 변경되었습니다 지금은 노조 내에서 반환 된 데이터를 포함 할 필요가 :

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) 

문제 단, I는 eggheadcafe에 게일 에릭슨 [MS]에 의해 포스트에 따라 100보다 큰 것으로 재귀를 설정할 필요가있다, 이것은 현재 지원되지 않습니다.

(임시가 아님) 테이블에 날짜가있는 테이블을 만들지 않고이 작업을 수행 할 수있는 방법이 있습니까?

저는 SqlServer2005를 사용하고 있습니다. 이 같은

+0

I가 지원하는 최대 레벨이 2^15 해결 기억하고 있으면 재귀 레벨 (100)보다 높은 값으로 설정하는 것이 가능하다. – Faiz

답변

6

날짜를 전달하면 영원히 실행할 수 귀하 가장 좋은 방법은 실제 날짜 표를 실제로 만드는 것입니다. 오랜 기간 동안 그렇게 많은 것은 없으며 임시 테이블이나 반복적 인 cte에서 on-the-fly로 실현하는 것보다 훨씬 빠릅니다. 당신이 선택 (또는 필요) 임시 테이블이 아닌 영구적 인 하나 가면

+1

당신이 날짜 테이블을 갖고 싶지 않다면 중간 해결책은 숫자의 작은 테이블 (0에서 1000까지)을 사용하고 과 같은 것을 선택하는 것입니다. cast (@minDate as datetime) + Val from tblNumbers 여기서 val <= (캐스팅 (datetime으로 @minDate) - 캐스트 (@maxDate는 datetime)) (Val은 tblNumber의 INT 필드이고 0, 1, 2 ... 값을 가짐) – mjv

+0

감사합니다. 실제 테이블을 사용하기로 결정했는데 단지 날짜를 저장하는 하나의 열이있는 테이블을 갖는 것이 좋지 않은 것처럼 보입니다. –

+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, 나는 호기심이 있습니다. 솔루션의? –

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 

그리고 테스트 전화를 이동

DECLARE 
    @MinDate datetime 
,@MaxDate datetime 

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

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

Wierd - 오늘은 집계 테이블이 포함 된 세 번째 소장입니다. 계속되는 이상한 태양 흑점 활동이어야합니다. 여기 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! 같은 해결책을 찾기 전에 이것을 보지 못했습니다. –