SQL 根据时间戳查询 select 按小时(列)和工作日(行)分组的值

SQL query to select values grouped by hour(col) and weekday(row) based on the timestamp

这个问题我在SO里搜索了一下,找到了稍微相似的帖子,但是无法适应我的需求。

我有一个包含服务器请求的数据库,每个服务器请求都有一个时间戳,我正在尝试提出一个允许我创建热矩阵图 (CCC HeatGrid) 的查询。

sql查询结果必须表示按每个工作日的每小时分组的服务器负载。

像这样:Example table

我只需要 SQL 查询,我知道如何创建图表。

谢谢,

这些看起来像 "counts" 行。

其中一个问题是 "sparse" 数据,我们可以稍后解决。

要获取星期几('Sunday'、'Monday' 等)returned,您可以使用 DATE_FORMAT 函数。为了让这些排序,我们需要包含一个整数值 0 到 6,或 1 到 7。我们可以在该表达式上使用 ORDER BY 子句来按我们想要的顺序获取行 returned。

为了让 "hour" 排在首位,我们可以在 SELECT 列表中使用有条件地递增计数的表达式。

假设您的时间戳列命名为 ts,并假设您想要从 2014 年提取所有行,我们从这样的事情开始:

SELECT DAYOFWEEK(t.ts)
     , DATE_FORMAT(t.ts,'%W')

  FROM mytable t
 WHERE t.ts >= '2014-01-01'
   AND t.ts <  '2015-01-01'
 GROUP BY DAYOFWEEK(t.ts)
 ORDER BY DAYOFWEEK(t.ts)

(我需要查看 MySQL 文档,WEEKDAYDAYOFWEEK 非常相似,但我们想要 returns星期天的最低值,星期六的最高值...我想我们想要 DAYOFWEEK,以后很容易修复)

"trick" 现在是横跨顶部的列。

我们可以使用 DATE_FORMAT() 函数、HOUR() 函数或 EXTRACT() 函数从时间戳中提取 "hour"...随您选择。

如果时间戳在指定的小时内,我们想要的表达式将 return 为 1,否则为 0。然后,我们可以使用 SUM() 聚合来计算 1。布尔表达式 returns 值为 1 表示 TRUE,0 表示 FALSE。

     , SUM( HOUR(t.ts)=0  )  AS `h0`
     , SUM( HOUR(t.ts)=1  )  AS `h1`
     , SUM( HOUR(t.ts)=2  )  AS `h2`
     , '...'
     , SUM( HOUR(t.ts)=22 )  AS `h22`
     , SUM( HOUR(t.ts)=23 )  AS `h23`

布尔表达式也可以计算为 NULL,但由于我们有一个谓词(即 WHERE 子句中的条件)确保 ts 不能为 NULL,所以这不会成为问题.

我们可能遇到的另一个问题(正如我之前提到的)是“稀疏”数据。为了说明这一点,考虑一下如果 没有 行具有 Mondayts 值,会发生什么情况(对于我们的查询)。结果是我们没有在 Monday 的结果集中得到一行。如果确实发生 "missing" 行 Monday(或一周中的任何一天),我们确实知道 "missing" Monday 行的所有每小时计数都将为零。