【问题标题】:Group dates by 7 days excluding specific dates按 7 天分组日期,不包括特定日期
【发布时间】:2016-11-24 09:36:44
【问题描述】:

我需要查询,我可以从月初开始每 7 天对日期进行分组。问题是我必须排除一些日子,特别是节假日前后的几天。在我的 DateDay 维度中有一个列,这表明它是哪一天的类型。 11 月的日历示例:

DTD_GID     DTD_Date    DTD_DayType
20161101    2016-11-01  2 --holiday was on 2016-10-31
20161102    2016-11-02  0
20161103    2016-11-03  0
20161104    2016-11-04  0
20161105    2016-11-05  0
20161106    2016-11-06  0
20161107    2016-11-07  0
20161108    2016-11-08  0
20161109    2016-11-09  0
20161110    2016-11-10  2
20161111    2016-11-11  1--public holiday
20161112    2016-11-12  2
20161113    2016-11-13  0
20161114    2016-11-14  0
20161115    2016-11-15  0
20161116    2016-11-16  0
20161117    2016-11-17  0
20161118    2016-11-18  0
20161119    2016-11-19  0
20161120    2016-11-20  0
20161121    2016-11-21  0
20161122    2016-11-22  0
20161123    2016-11-23  0
20161124    2016-11-24  0
20161125    2016-11-25  0
20161126    2016-11-26  0
20161127    2016-11-27  0
20161128    2016-11-28  0
20161129    2016-11-29  0
20161130    2016-11-30  0

我需要这样分组:

1: 2016-11-02 - 2016-11-08 (inclusive)
2: 2016-11-13 - 2016-11-19
3: 2016-11-20 - 2016-11-26

如果此类组少于 7 天,则不应通过查询返回。

如果您需要更多详细信息,请告诉我。

编辑:我不确定它是否会有所帮助,但我编写了以周为单位计算适当天数的查询

SELECT
     DTD_DTMGID
     ,CONVERT(VARCHAR(5), DATEADD(WK, Week, 0), 103) + ' - ' + CONVERT(VARCHAR(5), DATEADD(DD, 6, DATEADD(WK, Week, 0)), 103) AS Week
     ,Cnt
FROM (
    SELECT
        DTD_DTMGID
        , DATEDIFF(WK, 0, DTD_DATE) AS Week 
        , COUNT(*) AS Cnt
    FROM DIM_DateDay
    WHERE DTD_DayType = 0
    GROUP BY DTD_DTMGID ,DATEDIFF(WK, 0, DTD_DATE)
) AS X   
ORDER BY DTD_DTMGID 

结果:

DTD_DTMGID  Week            Cnt
201301      31/12 - 06/01   2
201301      07/01 - 13/01   5
201301      14/01 - 20/01   7
201301      21/01 - 27/01   7
201301      28/01 - 03/02   5
201302      28/01 - 03/02   2

EDIT2:作为输出,我期望这些组中的天数。作为 ID,我的意思是 DTD_GID 列,它是我的 DateDay 维度中的主键。 所以对于第 1 组)我会得到以下列表:

20161102
20161103
20161104
20161105
20161106
20161107
20161108

【问题讨论】:

  • 指定您的详细预期输出。您的预期输出不清楚。
  • @Mansoor 我在上次编辑中添加了预期的输出
  • 如果我提供一个按组返回成对日期的查询会怎样?

标签: sql sql-server tsql date sql-server-2012


【解决方案1】:

这是一种解决方案,可为您提供每个 7 天范围的开始和结束日期:

WITH CTE1 AS (
    SELECT DTD_Date, DATEDIFF(DAY, ROW_NUMBER() OVER (ORDER BY DTD_Date), DTD_Date) AS Group1 
    FROM #Table1
    WHERE DTD_DayType = 0
), CTE2 AS (
    SELECT DTD_Date, Group1, (ROW_NUMBER() OVER (PARTITION BY Group1 ORDER BY Group1) - 1) / 7 AS Group2
    FROM CTE1
)
SELECT MIN(DTD_Date) AS DTD_From, MAX(DTD_Date) AS DTD_Upto, COUNT(DTD_Date) AS C
FROM CTE2
GROUP BY Group1, Group2
ORDER BY DTD_From
-- HAVING COUNT(*) >= 7

输出:

DTD_From   | DTD_Upto   | C
-----------+------------+--
2016-11-02 | 2016-11-08 | 7
2016-11-09 | 2016-11-09 | 1
2016-11-13 | 2016-11-19 | 7
2016-11-20 | 2016-11-26 | 7
2016-11-27 | 2016-11-30 | 4

这是它的工作原理:

  • 第一个 CTE 删除假期并将组号分配给剩余的行。连续日期获得相同的组号(请参阅this question)。
  • 第二个 CTE 为每个组中的每一行分配另一个组号。第 1-7 行得到 0,第 8-14 行得到 1,依此类推。
  • 最后按组号对结果进行分组。

【讨论】:

  • 这正是我想要的。谢谢!
  • 这拯救了我的一天。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
相关资源
最近更新 更多