【问题标题】:Grouping Date Range by Week按周分组日期范围
【发布时间】:2010-10-29 07:49:59
【问题描述】:

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

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

(开始日期以“05/27/2007”开头,而不是“05/29/2007”,因为工作日的开始是星期日,而“05/27/2007”是“05/29”的一周的第一天/2007' 和最后一个 EndDate 的推理相同,即 2009 年 5 月 30 日,即星期六)

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

[UPDATE]这是我的最终查询

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

【问题讨论】:

  • 感谢您发布带有最终结果的更新。大多数人没有意识到它对其他人有多大帮助。

标签: sql tsql datetime date-range


【解决方案1】:
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

这将生成一个包含您需要的范围的行集。

【讨论】:

  • @Quassnoi:CTE 的递归内容很棒。让我尝试在我的查询中使用它。
【解决方案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

【讨论】:

  • 我试图找出我需要从您的查询中提取哪些“变量”。让我看看……
  • 我使用@my_date 只是为了让它在没有桌子的情况下运行。那将是您在 2007 年 5 月 29 日拥有的列或变量。如果您将其基于当前日期,则只需为其设置一个变量并使用它。看看 Quassnoi,您可能想要一组日期范围而不是单个日期范围,因此这可能无法完全回答您的问题。如果需要,您可以加入数字表或日历表以扩展它,或者像 Quassnoi 所做的那样加入 CTE。
【解决方案3】:

在您的 SQL 语句中应该非常简单直接...我在处理日期和日期算术方面有着悠久的历史,所以我会采用类似的方法:

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 调用中查看真实日期...

【讨论】:

  • @DRapp:我不是从表中检索日期,而是从日期范围中检索日期。不过谢谢你的回答。
猜你喜欢
  • 2011-03-02
  • 1970-01-01
  • 2013-11-04
  • 2021-11-16
  • 1970-01-01
  • 2013-05-19
  • 2010-10-31
相关资源
最近更新 更多