2016-11-09 3 views
0

CTE를 사용하여 7 개의 연속 날짜를 생성하려고합니다. 왜 다음 코드가 작동하는지 궁금합니다.SQL Server CTE 퍼즐

DECLARE @from DATE = '20160911', @to DATE = '20160917'; 

WITH seven_consecutive_dates AS 
(
    SELECT @from date 

    UNION ALL 

    SELECT DATEADD(DAY, 1, scd.date) 
    FROM seven_consecutive_dates scd 
    WHERE DATEADD(DAY, 1, scd.date) <= @to 
) 
SELECT * 
FROM seven_consecutive_dates 

?

다음과 같은하지 않습니다 :

난 단지 시작하거나 날짜를 종료 한 경우 어떻게
DECLARE @from DATE = '20160911', @to DATE = '20160917'; 

WITH seven_consecutive_dates AS 
(
    SELECT @from date 

    UNION ALL 

    SELECT DATEADD(DAY, 1, scd.date) 
    FROM seven_consecutive_dates scd 
    WHERE DATEDIFF(DAY, DATEADD(DAY, 1, scd.date), @to) < 6 
) 
SELECT * 
FROM seven_consecutive_dates 

? SEVEN 연속 날짜의 생성은 어떻게해야합니까?

+2

@to 이전 날짜의 경우 다 tediff는 6보다 작으며, 첫 번째 날짜가 증가하기 때문에 점진적으로 음수로 감소합니다. 예 : datediff (day, tomorrow, today)는 -1, datediff (오늘, 오늘부터 2 일후)는 -2 등입니다. 음수는 6보다 작습니다.이를 수정하려면 '< 6' to '> = 0'을 변경하십시오. – ZLK

+0

'SELECT'목록에 추가하여 디버깅하십시오. http://rextester.com/DYDPOC85714 –

답변

0

TVF를 사용하여 동적 날짜/시간 범위를 만듭니다. 재귀 CTE보다 더 빠르게하고 날짜 범위, 날짜 부분을 정의하고, 예를 들면 그래서

를 증가 :

Select * from [dbo].[udf-Range-Date]('20160911','20160917','DD',1) 

반환

RetSeq RetVal 
1  2016-09-11 00:00:00.000 
2  2016-09-12 00:00:00.000 
3  2016-09-13 00:00:00.000 
4  2016-09-14 00:00:00.000 
5  2016-09-15 00:00:00.000 
6  2016-09-16 00:00:00.000 
7  2016-09-17 00:00:00.000 

UDF 관심이 경우

CREATE FUNCTION [dbo].[udf-Range-Date] (@R1 datetime,@R2 datetime,@Part varchar(10),@Incr int) 
Returns Table 
Return (
    with cte0(M) As (Select 1+Case @Part When 'YY' then DateDiff(YY,@R1,@R2)/@Incr When 'QQ' then DateDiff(QQ,@R1,@R2)/@Incr When 'MM' then DateDiff(MM,@R1,@R2)/@Incr When 'WK' then DateDiff(WK,@R1,@R2)/@Incr When 'DD' then DateDiff(DD,@R1,@R2)/@Incr When 'HH' then DateDiff(HH,@R1,@R2)/@Incr When 'MI' then DateDiff(MI,@R1,@R2)/@Incr When 'SS' then DateDiff(SS,@R1,@R2)/@Incr End), 
     cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)), 
     cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a, cte1 b, cte1 c, cte1 d, cte1 e, cte1 f, cte1 g, cte1 h), 
     cte3(N,D) As (Select 0,@R1 Union All Select N,Case @Part When 'YY' then DateAdd(YY, N*@Incr, @R1) When 'QQ' then DateAdd(QQ, N*@Incr, @R1) When 'MM' then DateAdd(MM, N*@Incr, @R1) When 'WK' then DateAdd(WK, N*@Incr, @R1) When 'DD' then DateAdd(DD, N*@Incr, @R1) When 'HH' then DateAdd(HH, N*@Incr, @R1) When 'MI' then DateAdd(MI, N*@Incr, @R1) When 'SS' then DateAdd(SS, N*@Incr, @R1) End From cte2) 

    Select RetSeq = N+1 
      ,RetVal = D 
    From cte3,cte0 
    Where D<[email protected] 
) 
/* 
Max 100 million observations -- Date Parts YY QQ MM WK DD HH MI SS 
Syntax: 
Select * from [dbo].[udf-Range-Date]('2016-10-01','2020-10-01','YY',1) 
Select * from [dbo].[udf-Range-Date]('2016-01-01','2017-01-01','MM',1) 
*/