sql - 按 7 天分组日期,不包括特定日期

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

我需要查询,我可以从月初开始按每 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。作为 ID,我的意思是 DTD_GID 列,它是我的 DateDay 维度中的主键。 所以对于第 1 组)我会得到以下列表:

20161102
20161103
20161104
20161105
20161106
20161107
20161108

最佳答案

这是一个为您提供每个 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,依此类推。
  • 最后,您按组号对结果进行分组。

关于sql - 按 7 天分组日期,不包括特定日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40782640/

相关文章:

mysql - 如何在 MySQL 中仅对一列应用 DISTINCT 选择器

sql - 如何在不应用透视功能的情况下为不同的字段创建列

sql-server - SQL Server 中的临时表

sql - 从sql server中的字符串中提取单词

sql - 根据动态列查找匹配记录

python - pypyodbc:关键字 "WITH"附近的 OPENJSON 语法不正确

ios - ORDER BY 子句在 iphone 应用程序的 simpledb amazon 中不起作用

tsql - 删除所有登录名,其中 loginname 像

sql - 获取表详细信息

tsql - T-SQL:在OUTPUT子句中插入INSERT原始值