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 文档,WEEKDAY
和 DAYOFWEEK
非常相似,但我们想要 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,所以这不会成为问题.
我们可能遇到的另一个问题(正如我之前提到的)是“稀疏”数据。为了说明这一点,考虑一下如果 没有 行具有 Monday
的 ts
值,会发生什么情况(对于我们的查询)。结果是我们没有在 Monday
的结果集中得到一行。如果确实发生 "missing" 行 Monday
(或一周中的任何一天),我们确实知道 "missing" Monday
行的所有每小时计数都将为零。
这个问题我在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 文档,WEEKDAY
和 DAYOFWEEK
非常相似,但我们想要 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,所以这不会成为问题.
我们可能遇到的另一个问题(正如我之前提到的)是“稀疏”数据。为了说明这一点,考虑一下如果 没有 行具有 Monday
的 ts
值,会发生什么情况(对于我们的查询)。结果是我们没有在 Monday
的结果集中得到一行。如果确实发生 "missing" 行 Monday
(或一周中的任何一天),我们确实知道 "missing" Monday
行的所有每小时计数都将为零。