Tsql T-SQL CTE周序列

Tsql T-SQL CTE周序列,tsql,Tsql,我正试图写一个递归的CTE,给我一个从第38周开始的周一序列,在接下来的20周里持续6年。我需要绘制过去6年的每周销售数据图,并认为递归CTE将是动态创建周一日期序列的最佳方法。这有点复杂,因为这个赛季一直延续到明年。下面是我希望记录集的外观示例: 9/17/2012 9/24/2012 10/1/2012 10/8/2012 10/15/2012 10/22/2012 10/29/2012 11/5/2012 11/12/2012 11/19/2012 11/26/2012 12/3/2012

我正试图写一个递归的CTE,给我一个从第38周开始的周一序列,在接下来的20周里持续6年。我需要绘制过去6年的每周销售数据图,并认为递归CTE将是动态创建周一日期序列的最佳方法。这有点复杂,因为这个赛季一直延续到明年。下面是我希望记录集的外观示例:

9/17/2012
9/24/2012
10/1/2012
10/8/2012
10/15/2012
10/22/2012
10/29/2012
11/5/2012
11/12/2012
11/19/2012
11/26/2012
12/3/2012
12/10/2012
12/17/2012
12/24/2012
12/31/2012
1/7/2013
1/14/2013
1/21/2013
1/28/2013
2/4/2013
2/11/2013
2/18/2013
2/25/2013
9/16/2013  <-next season start
9/23/2013
9/30/2013
10/7/2013
10/14/2013
10/21/2013
10/28/2013
11/4/2013
11/11/2013
11/18/2013
11/25/2013
12/2/2013
12/9/2013
12/16/2013
12/23/2013
12/30/2013
1/6/2014
1/13/2014
1/20/2014
1/27/2014
2/3/2014
2/10/2014
2/17/2014
2/24/2014

我不知道这是否可能,但似乎是可能的。我想我可能需要使用多个CTE来实现这一点,但我真的很难做到这一点。非常感谢您提供的任何帮助或指导。

如果您只是在表中查找周一,您可以使用DATENAMEWEEKDAY、[ColumnName]来测试周一

例如,以下代码将在假设销售表中查找所有周一销售日期:

从那里,您可以应用开始日期、结束日期等所需的任何附加条件

现在,如果您只是想生成所有周一的列表,可以使用一个表变量和一个WHILE循环:


不管怎样,我绝对不认为你需要CTE来完成这个任务。

所以我想出来了。valverij的答案也同样有效。下面是我使用2个递归CTE得出的结论。如果有人发现它有什么问题,请告诉我

WITH Seasons(StartDate) AS
(
    SELECT DATEADD(m, 4, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)) AS StartDate UNION ALL
    SELECT DATEADD(yy, -1, StartDate)
    FROM Seasons
    WHERE YEAR(StartDate) > YEAR(GETDATE()) - 6
),
Weeks(StartDate, WeekStartDate) AS
(
    SELECT DATEADD(d, 1 - DATEPART(dw, DATEADD(wk, 20, Seasons.StartDate)), DATEADD(wk, 20, Seasons.StartDate)), DATEADD(d, 1 - DATEPART(dw, DATEADD(wk, 20, Seasons.StartDate)), DATEADD(wk, 20, Seasons.StartDate)) AS WeekStartDate
    FROM Seasons UNION ALL
    SELECT StartDate, DATEADD(wk, 1, WeekStartDate)
    FROM Weeks
    WHERE (WeekStartDate < DATEADD(wk, 23, StartDate))
)
SELECT StartDate, WeekStartDate
FROM Weeks
ORDER BY WeekStartDate DESC

我一遍又一遍地读你的帖子。我还是不明白你需要什么我觉得很难解释。我正在寻找一种方法,可以在一年的第38周和下一年的第9周之间动态生成一组星期一的结果。这样我就有1个销售季了。我需要在过去的6个赛季里做到这一点。我希望有一个CTE生成的日期列表。如果日期都在一行中,那么使用递归CTE是很容易的,但是我不想看到3月到8月的日期。我认为CTE比while循环和插入temp表更快。如果不是这样的话,请纠正我。当然可以,但这完全取决于你的需要。即使将该日期追溯到2000年2月7日,也只需约170毫秒。如果你只需要一个周一的列表来进行一次性查询,我认为这样的事情很好。如果您需要它作为应用程序的存储过程,那么它可能会根据服务器负载的不同而降低速度,当然,它将用于提供SSRS报告的存储过程中。用户需要能够输入开始和结束。是否有任何原因表明@StartDate和@EndDate之间的DATENAMEweekday、[MyDate]=“Monday”和[MyDate]不起作用请参见第一个示例?除非您正在处理一些过于复杂的表模式,否则我仍然不确定这里是否需要CTE。没有理由它不工作,但我最终找到了一种使用2个递归CTE的方法。
DECLARE @Mondays TABLE(MondayDate datetime)
DECLARE @CurrentDate datetime = '02/07/2013' -- one year ago

WHILE @CurrentDate <= GETDATE() BEGIN
    IF DATENAME(WEEKDAY, @CurrentDate) = 'Monday'
        INSERT INTO @Mondays VALUES(@CurrentDate)
    SET @CurrentDate = @CurrentDate + 1
END

SELECT *
FROM @Mondays
WITH Seasons(StartDate) AS
(
    SELECT DATEADD(m, 4, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)) AS StartDate UNION ALL
    SELECT DATEADD(yy, -1, StartDate)
    FROM Seasons
    WHERE YEAR(StartDate) > YEAR(GETDATE()) - 6
),
Weeks(StartDate, WeekStartDate) AS
(
    SELECT DATEADD(d, 1 - DATEPART(dw, DATEADD(wk, 20, Seasons.StartDate)), DATEADD(wk, 20, Seasons.StartDate)), DATEADD(d, 1 - DATEPART(dw, DATEADD(wk, 20, Seasons.StartDate)), DATEADD(wk, 20, Seasons.StartDate)) AS WeekStartDate
    FROM Seasons UNION ALL
    SELECT StartDate, DATEADD(wk, 1, WeekStartDate)
    FROM Weeks
    WHERE (WeekStartDate < DATEADD(wk, 23, StartDate))
)
SELECT StartDate, WeekStartDate
FROM Weeks
ORDER BY WeekStartDate DESC