我有一个如下所示的数据库表:
id | macaddr | load | timestamp
=========================================
1 | 0011111 | 17 | 2012-02-07 10:00:00
1 | 0011111 | 6 | 2012-02-07 12:00:00
2 | 0022222 | 3 | 2012-02-07 12:00:03
3 | 0033333 | 9 | 2012-02-07 12:00:04
4 | 0022222 | 4 | 2012-02-07 12:00:06
5 | 0033333 | 8 | 2012-02-07 12:00:10
...
现在,我想计算不同时间段内所有设备(= mac 地址)的平均负载,例如今天、昨天、本周、本月。
可以通过首先找出不同时间点(采样日期)的总负载总和,然后计算这些采样日期的负载总和的平均值来计算平均负载。例如,如果我想要最后十秒的平均负载(现在是 2012-02-07 12:00:10),我可以决定我的示例日期是 12:00:02、12:00: 04、12:00:06、12:00:08 和 12:00:10。然后,我将通过汇总每个设备的最新负载值来计算负载总和:
2012-02-07 12:00:02 | 6 [= load(id=2)]
2012-02-07 12:00:04 | 18 [= load(id=2) + load(id=3) + load(id=4)]
2012-02-07 12:00:06 | 19 [= load(id=2) + load(id=4) + load(id=5)]
2012-02-07 12:00:08 | 19 [= load(id=2) + load(id=4) + load(id=5)]
2012-02-07 12:00:10 | 18 [= load(id=2) + load(id=5) + load(id=6)]
如果设备的负载值早于例如一个小时(这里发生在 id=1),则忽略该设备的负载值。在这种情况下,平均值为 16。
目前,我生成了一个相当复杂的查询,其中包含许多非常慢的“UNION ALL”语句:
SELECT avg(l.load_sum) as avg_load
FROM (
SELECT sum(so.load) AS load_sum
FROM (
SELECT *
FROM (
SELECT si.macaddr, si.load
FROM sensor_data si WHERE si.timestamp > '2012-02-07 11:00:10' AND si.timestamp < '2012-02-07 12:00:10'
ORDER BY si.timestamp DESC
) AS sm
GROUP BY macaddr
) so
UNION ALL
[THE SAME THING AGAIN WITH OTHER TIMESTAMPS]
UNION ALL
[AND AGAIN]
UNION ALL
[AND AGAIN]
...
) l
现在想象一下,我想计算一整月的平均负载。对于每小时采样日期,我需要使用 UNION ALL 语句加入 30x24=720 个查询。在我的机器上完成整个查询需要将近一分钟。我确信没有 UNION ALL 语句会有更好的解决方案。但是,我没有在网上找到任何有用的东西。因此,我将非常感谢您的帮助!