2016-11-09 122 views
0

我想使用CTE生成七個連續日期。我想知道爲什麼下面的代碼工作: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之前的日期,da tediff小於6,並且由於第一次日期增長,它逐漸減少(變成負數)。例如datediff(日期,明天,今天)是-1,(日期,從現在起兩天,今天)是-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) 
*/