我曾经在SQL Server中进行过这种查询。我对MySQL的深度不足。
我希望我能够沟通的是,我希望根据noise_detail
和一天中的时间对monitor_id
个记录进行分组,但在每一行,我想要每个聚合行的noise_level
列的平均值,然后是每个聚合行中count(*)
行的平均值。
以下是我们正在跟踪的原始事件的一些示例数据。
OY VEH。严重编辑=再次=解释源数据......
此示例数据中的每一行代表一个“噪音事件”'来自数十个显示器,每个显示器编码为' SEA01,SEA02,SEA03等。)它们每天每小时都会读取数十个读数。
了解在一定日期范围内凌晨3点发生的事件的平均数非常重要。所以:在1月1日凌晨3点在SEA01上进行COUNT()事件,然后在1月2日凌晨3点在SEA01举行COUNT()事件等等,然后给我-average- for所有这些日期。
我们还需要知道每个监视器每小时的平均噪音水平。所以类似地,在1月1日凌晨3点在SEA01上获取事件的AVG(noise_level),然后在1月2日凌晨3点在SEA01上获取事件的AVERAGE(noise_level)等等,然后给我所有那些日期的-average-。
ID monitor_id time noise_level
393211 SEA14 2016-03-22 15:39:00 79
393245 SEA11 2016-03-05 07:20:00 81.6
338262 SEA15 2016-02-28 19:44:00 80.4
338263 SEA14 2016-02-28 19:55:00 74.2
338264 SEA14 2016-02-28 19:54:00 81.5
338265 SEA14 2016-02-28 19:44:00 73.4
338266 SEA13 2016-02-28 19:54:00 81
338267 SEA13 2016-02-28 19:43:00 94.3
338268 SEA12 2016-02-28 19:43:00 80.2
338269 SEA11 2016-02-28 19:53:00 89
338270 SEA11 2016-02-28 19:43:00 89.5
338271 SEA09 2016-02-28 19:43:00 75.2
338272 SEA09 2016-02-28 19:42:00 73.9
338273 SEA09 2016-02-28 19:41:00 85.1
338588 SEA28 2016-02-29 05:04:00 83.3
338589 SEA22 2016-02-29 05:04:00 82.7
338590 SEA21 2016-02-29 05:04:00 82.9
338591 SEA20 2016-02-29 05:04:00 84.1
338592 SEA19 2016-02-29 05:03:00 88.6
338593 SEA18 2016-02-29 05:03:00 85.5
338594 SEA17 2016-02-29 05:03:00 86.6
338749 SEA14 2016-02-28 20:43:00 83
所以我需要的是看起来像这样:(注意:这是完整报告中的一个样本,它不是从上面的子集中挑选出来的。)
NOISE REPORT FROM 01/01/2016 - 06/30/2016 SHOWING AVGS FOR EACH HOUR
=================================================
avg avg
monitor_id hour num_events/hr noise_level for each hour
SEA11 03AM 12 70.3
SEA11 04AM 55 81.6
SEA11 05AM 27 83.2
SEA11 06AM 16 79.6
....etc.
SEA12 03AM 21 72.7
SEA12 04AM 45 83.1
SEA12 05AM 17 87.9
SEA12 06AM 26 77.6
....etc.
...所以我需要每个监视器/小时一行,其中在一个日期范围内发生在该小时内的平均事件数,然后是-average- noise_level,再次针对每小时发生的所有事件跨越一系列日期。
EG。第6行'发生在1月1日至6月30日凌晨4点的Monitor SEA12'的平均事件数。
这是我到目前为止,它的伪代码'这显然不会起作用,但我希望它能表达我想要实现的目标:
SELECT time,
monitor_id,
AVG( SELECT COUNT(*) FROM noise_detail nc WHERE nc.monitor_id = n.monitor_id ) AS average_number_of_events, // avg number of events at X'o'clock
SELECT AVG(noise_level) FROM noise_detail nl WHERE nl.monitor_id = n.monitor_id) AS average_noise_level // avg noise level at X'o'clock
FROM noise_detail AS n
GROUP by monitor_id, SUBSTR(time,12,2) // group by monitor and X'o'clock (the hour of the day in 24 hr format)
答案 0 :(得分:1)
这是第二次尝试。请注意,使用的数据与问题中的数据不同,请参阅SQL Fiddle
中的此版本MySQL 5.6架构设置:
CREATE TABLE noise_detail
(`ID` int, `monitor_id` varchar(5), `time` datetime, `noise_level` int)
;
INSERT INTO noise_detail
(`ID`, `monitor_id`, `time`, `noise_level`)
VALUES
(338271, 'SEA09', '2016-02-24 18:43:00', 75.2),
(338272, 'SEA09', '2016-02-24 18:42:00', 73.9),
(338273, 'SEA09', '2016-02-24 18:41:00', 85.1),
(338271, 'SEA09', '2016-02-24 19:43:00', 75.2),
(338272, 'SEA09', '2016-02-24 19:42:00', 73.9),
(338273, 'SEA09', '2016-02-24 19:41:00', 85.1),
(338271, 'SEA09', '2016-02-25 19:43:00', 75.2),
(338272, 'SEA09', '2016-02-25 19:42:00', 73.9),
(338273, 'SEA09', '2016-02-25 19:41:00', 85.1),
(338271, 'SEA09', '2016-02-26 18:43:00', 75.2),
(338272, 'SEA09', '2016-02-26 18:42:00', 73.9),
(338273, 'SEA09', '2016-02-26 18:41:00', 85.1),
(338271, 'SEA09', '2016-02-26 19:43:00', 75.2),
(338272, 'SEA09', '2016-02-26 19:42:00', 73.9),
(338273, 'SEA09', '2016-02-26 19:41:00', 85.1),
(338271, 'SEA09', '2016-02-28 19:43:00', 75.2),
(338272, 'SEA09', '2016-02-28 19:42:00', 73.9),
(338273, 'SEA09', '2016-02-28 19:41:00', 85.1),
(338271, 'SEA09', '2016-02-28 19:43:00', 75.2),
(338272, 'SEA09', '2016-02-28 19:42:00', 73.9),
(338273, 'SEA09', '2016-02-28 19:41:00', 85.1)
;
<强>查询强>:
SELECT
monitor_id
, HOUR(time)
, COUNT(*) as tot_events_in_hour
, COUNT(*) / COUNT(DISTINCT DAY(time)) as av_events_ph
, AVG(noise_level) AS av_noise_level_in_hour
, AVG(noise_level) / COUNT(DISTINCT DAY(time)) AS av_noise_level_ph
FROM noise_detail n
GROUP BY
monitor_id
, HOUR(time)
ORDER BY
monitor_id
, HOUR(time)
<强> Results 强>:
| monitor_id | HOUR(time) | tot_events_in_hour | av_events_ph | av_noise_level_in_hour | av_noise_level_ph |
|------------|------------|--------------------|--------------|------------------------|-------------------|
| SEA09 | 18 | 6 | 3 | 78 | 39 |
| SEA09 | 19 | 15 | 3.75 | 78 | 19.5 |
日常/时间数据以人类可读的格式存储是一种常见的误解。列time
很可能不会以这种方式存储,因此为字符串设计的substr()不适合确定一天中的小时。你需要日期/时间函数。
MySQL 5.6架构设置:
CREATE TABLE noise_detail
(`ID` int, `monitor_id` varchar(5), `time` datetime, `noise_level` int)
;
INSERT INTO noise_detail
(`ID`, `monitor_id`, `time`, `noise_level`)
VALUES
(393211, 'SEA14', '2016-03-22 15:39:00', 79),
(393245, 'SEA11', '2016-03-05 07:20:00', 81.6),
(338262, 'SEA15', '2016-02-28 19:44:00', 80.4),
(338263, 'SEA14', '2016-02-28 19:55:00', 74.2),
(338264, 'SEA14', '2016-02-28 19:54:00', 81.5),
(338265, 'SEA14', '2016-02-28 19:44:00', 73.4),
(338266, 'SEA13', '2016-02-28 19:54:00', 81),
(338267, 'SEA13', '2016-02-28 19:43:00', 94.3),
(338268, 'SEA12', '2016-02-28 19:43:00', 80.2),
(338269, 'SEA11', '2016-02-28 19:53:00', 89),
(338270, 'SEA11', '2016-02-28 19:43:00', 89.5),
(338271, 'SEA09', '2016-02-28 19:43:00', 75.2),
(338272, 'SEA09', '2016-02-28 19:42:00', 73.9),
(338273, 'SEA09', '2016-02-28 19:41:00', 85.1),
(338588, 'SEA28', '2016-02-29 05:04:00', 83.3),
(338589, 'SEA22', '2016-02-29 05:04:00', 82.7),
(338590, 'SEA21', '2016-02-29 05:04:00', 82.9),
(338591, 'SEA20', '2016-02-29 05:04:00', 84.1),
(338592, 'SEA19', '2016-02-29 05:03:00', 88.6),
(338593, 'SEA18', '2016-02-29 05:03:00', 85.5),
(338594, 'SEA17', '2016-02-29 05:03:00', 86.6),
(338749, 'SEA14', '2016-02-28 20:43:00', 83)
;
首次查询建议:
SELECT
monitor_id
, HOUR(time)
, COUNT(*) as number_of_events
, AVG(noise_level) AS average_noise_level
FROM noise_detail n
GROUP BY
monitor_id
, HOUR(time)
ORDER BY
monitor_id
, HOUR(time)
<强> Results 强>:
| monitor_id | HOUR(time) | number_of_events | average_noise_level |
|------------|------------|------------------|---------------------|
| SEA09 | 19 | 3 | 78 |
| SEA11 | 7 | 1 | 82 |
| SEA11 | 19 | 2 | 89.5 |
| SEA12 | 19 | 1 | 80 |
| SEA13 | 19 | 2 | 87.5 |
| SEA14 | 15 | 1 | 79 |
| SEA14 | 19 | 3 | 76.3333 |
| SEA14 | 20 | 1 | 83 |
| SEA15 | 19 | 1 | 80 |
| SEA17 | 5 | 1 | 87 |
| SEA18 | 5 | 1 | 86 |
| SEA19 | 5 | 1 | 89 |
| SEA20 | 5 | 1 | 84 |
| SEA21 | 5 | 1 | 83 |
| SEA22 | 5 | 1 | 83 |
| SEA28 | 5 | 1 | 83 |
答案 1 :(得分:0)
这样做你想要的吗?
SELECT time, monitor_id,
COUNT(*) as number_of_events,
AVG(noise_level) AS average_noise_level
FROM noise_detail nd
GROUP by monitor_id, SUBSTR(time, 12, 2);
我不确定substr(time, 12, 2)
应该做什么。如果time
存储为字符串,那么很好。如果作为日期/时间数据类型,则使用特定于这些类型的功能。