如何通过查询获得每小时的日期计数?

时间:2017-01-23 17:33:51

标签: sql-server sql-server-2008

在SQL中

如何根据日期时间的1小时持续时间间隔按查询编写计数。

我可以根据日期编写查询。但是日期和时间戳将是一个Pivot结构。

如何通过查询获得按小时计算的日期?

2017-01-02 05:27:10.117   Sam
2017-01-02 15:27:10.117   Sam
2017-01-03 06:27:10.116   Ben
2017-01-03 06:28:10.119   Aam

预期输出

CountByHour       05:00 to 06:00 AM    06:00 to 07:00 AM   15:00 to 16:00
2017-01-02          1                      0                  1
2017-01-03          0                      2                  0

3 个答案:

答案 0 :(得分:2)

此查询将以大致所需的格式返回数据透视表:

WITH t(d, h, n) AS (
  SELECT CAST(t AS DATE) AS d, h, COUNT(CASE WHEN h = datepart(hh, t) THEN 1 END) AS n
  FROM (
    VALUES 
      ('2017-01-02 05:27:10.117', 'Sam'),
      ('2017-01-02 15:27:10.117', 'Sam'),
      ('2017-01-03 06:27:10.116', 'Ben'),
      ('2017-01-03 06:28:10.119', 'Aam')
  ) AS t(t, s)
  CROSS JOIN (
    VALUES (0) , (1) , (2) , (3) , (4) , (5),
           (6) , (7) , (8) , (9) , (10), (11),
           (12), (13), (14), (15), (16), (17),
           (18), (19), (20), (21), (22), (23)
  ) AS h(h)
  GROUP BY CAST(t AS DATE), h
)
SELECT *
FROM t
PIVOT (
  sum(n) FOR h IN (
    [0] , [1] , [2] , [3] , [4] , [5], 
    [6] , [7] , [8] , [9] , [10], [11], 
    [12], [13], [14], [15], [16], [17],
    [18], [19], [20], [21], [22], [23]
  )
) t
ORDER BY d

说明:

  1. CROSS JOIN操作通过形成cartesian product将每个时间戳(t)与每天的小时(h)组合在一起(此处硬编码)。我最近在博客上发表了关于the utility of CROSS JOIN in this article here
  2. 的文章
  3. COUNT()聚合函数计算与实际小时匹配的行数(n)(时间戳)。
  4. 最后,PIVOTh列转换为单独的列

答案 1 :(得分:1)

我使用CAST,CONVERT和CASE语法解决了这个问题。思想可能对你有用。

SELECT CONVERT(VARCHAR(10),COL1,108)
       ,ISNULL(SUM(CASE WHEN CAST(SUBSTRING(CONVERT(VARCHAR(30),CAST (COL1 AS DATETIME),108),1,2) AS INT) >= 5 AND CAST(SUBSTRING(CONVERT(VARCHAR(30),CAST (COL1 AS DATETIME),108),1,2) AS INT) < 6
        THEN 1 END),0) AS [5_to_6]
       ,ISNULL(SUM(CASE WHEN CAST(SUBSTRING(CONVERT(VARCHAR(30),CAST (COL1 AS DATETIME),108),1,2) AS INT) >= 6 AND CAST(SUBSTRING(CONVERT(VARCHAR(30),CAST (COL1 AS DATETIME),108),1,2) AS INT) < 7
        THEN 1 END),0) AS [6_to_7] 
       ,ISNULL(SUM(CASE WHEN CAST(SUBSTRING(CONVERT(VARCHAR(30),CAST (COL1 AS DATETIME),108),1,2) AS INT) >= 15 AND CAST(SUBSTRING(CONVERT(VARCHAR(30),CAST (COL1 AS DATETIME),108),1,2) AS INT) < 16
        THEN 1 END),0) AS [15_to_16]

FROM 
            (VALUES('2017-01-02 05:27:10.117','Sam'),
            ('2017-01-02 15:27:10.117','Sam'),
            ('2017-01-03 06:27:10.116','Ben'),
            ('2017-01-03 06:28:10.119','Aam')) TC (COL1,COL2)
GROUP BY CONVERT(VARCHAR(10),COL1,108)
GO          

答案 2 :(得分:0)

为了能够透视数据,日期和小时需要驻留在不同的列中。你可以在你的PIVOT环境中做到这一点;作为中间结果(用名字组成):

select cast(eventdatetime as date) eventdate
  , datepart(hh, eventdatetime) eventhour
  , count(*) eventcount 
from mytable 
group by cast(eventdatetime as date), hour(eventdatetime)

这会给出结果(来自你的例子)

eventdate  eventhour
2017-01-02 5   1
2017-01-02 15   1
2017-01-03 6 2

然后你应该能够转向那个。