SQL Group By Day Range

时间:2016-01-31 06:53:18

标签: sql sql-server sql-server-2008-r2

我有一个表OutletVisit,其列DTOEntry为DateTime格式。

表格结构

DTOEntry  |  OutletID 
18-01-2016|     1     
18-01-2016|     2    
18-01-2016|     3     
18-01-2016|     4     
27-01-2016|     1     
27-01-2016|     2    
27-01-2016|     3     
29-01-2016|     4     

现在我想要的输出基本上是group byThursday [包含]到Wednesday

From      |  To        |  OutletID |  ActualDate 
14-01-2016| 20-01-2016 |   1       |  18-01-2016
14-01-2016| 20-01-2016 |   2       |  18-01-2016
14-01-2016| 20-01-2016 |   3       |  18-01-2016
14-01-2016| 20-01-2016 |   4       |  18-01-2016
21-01-2016| 27-01-2016 |   1       |  27-01-2016
21-01-2016| 27-01-2016 |   2       |  27-01-2016
21-01-2016| 27-01-2016 |   3       |  27-01-2016
28-01-2016| 03-02-2016 |   4       |  29-01-2016

如何为此编写动态SQL 提前致谢

1 个答案:

答案 0 :(得分:3)

目前尚不清楚为什么你需要"动态sql",但你可以使用日期函数计算每周四开始的一周。

  • datediff(day,fromdate,todate)返回的天数 整数
  • datediff(day,-4,DTOEntry)是1899年12月星期四的天数。
  • 将该数除以7(nb。这是整数结果)
  • 将该数字乘以7
  • 将该数字添加到-4以达到星期四开始的一周的日期

SQL Fiddle

MS SQL Server 2014架构设置

CREATE TABLE OutletVisit 
    ([DTOEntry] datetime, [OutletID] int)
;

INSERT INTO OutletVisit 
    ([DTOEntry], [OutletID])
VALUES
    ('2016-01-18 00:00:00', 1),
    ('2016-01-18 00:00:00', 2),
    ('2016-01-18 00:00:00', 3),
    ('2016-01-18 00:00:00', 4),
    ('2016-01-27 00:00:00', 1),
    ('2016-01-27 00:00:00', 2),
    ('2016-01-27 00:00:00', 3),
    ('2016-01-29 00:00:00', 4)
;

查询1

SELECT
      ca.weekstart
    , DATEADD(DAY, 6, ca.weekstart) AS weekfinish
    , ov.*
FROM OutletVisit ov
      CROSS APPLY (
            SELECT
                  DATEADD(DAY, (DATEDIFF(DAY, -4, DTOEntry) / 7) * 7, -4) AS weekstart
      ) AS ca

可以使用的替代方法,使用"派生表" (或"子查询"):

SELECT
      weekstart
    , DATEADD(DAY, 6, weekstart) AS weekfinish
    , DTOEntry
    , OutletID
FROM (
      SELECT
            DATEADD(DAY, (DATEDIFF(DAY, -4, DTOEntry) / 7) * 7, -4) AS weekstart
          , ov.DTOEntry
          , ov.OutletID
      FROM OutletVisit ov
      ) AS derived
;

<强> Results

|                 weekstart |                 weekfinish |                  DTOEntry | OutletID |
|---------------------------|----------------------------|---------------------------|----------|
| January, 14 2016 00:00:00 |  January, 20 2016 00:00:00 | January, 18 2016 00:00:00 |        1 |
| January, 14 2016 00:00:00 |  January, 20 2016 00:00:00 | January, 18 2016 00:00:00 |        2 |
| January, 14 2016 00:00:00 |  January, 20 2016 00:00:00 | January, 18 2016 00:00:00 |        3 |
| January, 14 2016 00:00:00 |  January, 20 2016 00:00:00 | January, 18 2016 00:00:00 |        4 |
| January, 21 2016 00:00:00 |  January, 27 2016 00:00:00 | January, 27 2016 00:00:00 |        1 |
| January, 21 2016 00:00:00 |  January, 27 2016 00:00:00 | January, 27 2016 00:00:00 |        2 |
| January, 21 2016 00:00:00 |  January, 27 2016 00:00:00 | January, 27 2016 00:00:00 |        3 |
| January, 28 2016 00:00:00 | February, 03 2016 00:00:00 | January, 29 2016 00:00:00 |        4 |

注意在输出时控制日期时间值的显示使用FORMAT()或CONVERT()。 Sqlfiddle的显示默认值已在上面的结果中使用。

请注意,实际上一周开始于(比如)2016年1月14日00:00:00,并于2016年1月21日00:00:00结束,持续7天。专栏&#34;周完成&#34;使用6天的持续时间来匹配您的预期结果。