2009-05-27 106 views
4

我有一个日期范围,开始日期是今天之前的2年。例如'05/29/2007'〜'05/29/2009'。按周分组日期范围

我该如何突破日期范围,以便获得如下列表?

(开始日期从“05/27/2007”开始,而不是“05/29/2007”,因为从星期一开始是星期天,'05/27/2007'是'05 /二千〇七分之二十九' 和同样的道理在过去的结束日期,二○○九年五月三十○日,这是星期六)

StartDate EndDate 
05/27/2007 06/02/2007 
06/03/2007 06/09/2007 
... 
05/24/2009 05/30/2009 

[更新]这里是我的最终查询

WITH hier(num, lvl) AS (
    SELECT 0, 1 
     UNION ALL 
    SELECT 100, 1 
     UNION ALL 
    SELECT num + 1, lvl + 1 
    FROM hier 
    WHERE lvl < 100 
) 
SELECT num, lvl, 
    DATEADD(dw, -DATEPART(dw, '2007-05-29'), '2007-05-29') + num * 7, 
    DATEADD(dw, -DATEPART(dw, '2007-05-29'), '2007-05-29') + (num + 1) * 7 
FROM hier 
where num <= 104 --; 52 weeks/year * 2 
ORDER BY num 
+0

感谢您发布最新结果的更新。大多数人没有意识到它对其他人有多大的帮助。 – Crimius 2012-08-16 12:44:35

回答

4
WITH hier(num, lvl) AS (
     SELECT 0, 1 
     UNION ALL 
     SELECT 100, 1 
     UNION ALL 
     SELECT num + 1, lvl + 1 
     FROM hier 
     WHERE lvl < 100 
     ) 
SELECT DATEADD(dw, -DATEPART(dw, '29.05.2007'), '29.05.2007') + num * 7, 
     DATEADD(dw, -DATEPART(dw, '29.05.2007'), '29.05.2007') + (num + 1) * 7 
FROM hier 
WHERE DATEADD(dw, -DATEPART(dw, '29.05.2007'), '29.05.2007') + num * 7 < '29.05.2009' 
ORDER BY 
     num 

这将产生你所需要的范围内的行集。

+0

@Quassnoi:与CTE的伟大的递归的东西。让我试着在我的查询中使用它。 – Sung 2009-05-27 16:17:03

2

您需要确保@@ DATEFIRST已正确发送,那么您可以简单地使用下面的代码。尽管如此,请阅读DATEFIRST,以便完全理解它。

SET DATEFIRST 1 

DECLARE @my_date DATETIME 

SET @my_date = '2007-05-29' 

SELECT 
    DATEADD(dw, -DATEPART(dw, @my_date), @my_date) AS StartDate, 
    DATEADD(dw, 6 - DATEPART(dw, @my_date), @my_date) AS EndDate 
+0

我想弄清楚我需要从查询中提取出什么“变量”。让我看看... – Sung 2009-05-27 16:03:51

+0

我使用@my_date只是为了让它在没有表格的情况下运行。那将是您在2007年5月29日提供的专栏或变量。如果您将其从当前日期中删除,则只需设置一个变量并使用它即可。看着Quassnoi的它看起来也许你想要一组日期范围而不是一个单一的日期范围,所以这可能不完全回答你的问题。您可以加入数字表格或日历表格,以根据需要扩展它,或者像Quassnoi所做的CTE一样。 – 2009-05-27 16:21:40

0

应该在你的SQL语句非常简单directy ......我已经处理日期和日期计算的一个很长的历史,所以我想办法是这样的:

select 
     datepart(year, YourDateField) as GroupYear, 
     datepart(week, (YourDateField - datepart(day, YourDateField) +1) as GroupWeek, 
     YourDateField, 
     OtherFields 
    from 
     YourTable 
    where 
     whateverDateRange... 
    group by 
    GroupYear, 
    GroupWeek 

的原因一年一周是如果你跨越多年,你会有第一年的第2周前两年的第1周,等等。

现在,数学如何工作...为GroupWeek。这实际上会根据您的数据的任何日期为基础计算一周中的第一天......假设您有今年5月25日,26日和27日的数据......他们分别是第2,3,4天星期日开始于第1天的星期。因此:

5月25日 - 2日(星期几)= 5月23日(星期六)+1 = 5月24日(星期日)。 5月26日至3日(星期)= 5月23日......等 5月27日至4日(星期)= 5月23日

因此,通过还包括有问题的原日期字段,你可以看到真正的日期全部在一个SQL调用中...