SQL选择3小时avg

时间:2016-02-06 12:54:56

标签: mysql datetime mariadb

我得到了这张桌子:

MariaDB [table]> 
select insert_time, host_id, tx 
from host_daily 
where host_id = 2 
order by insert_time desc 
limit 24;

+---------------------+---------+------------+
| insert_time         | host_id | tx         |
+---------------------+---------+------------+
| 2016-02-06 14:00:00 |       2 | 9676875156 |
| 2016-02-06 13:00:00 |       2 | 9671544048 |
| 2016-02-06 12:00:00 |       2 | 9669464371 |
| 2016-02-06 11:00:00 |       2 | 9667087098 |
| 2016-02-06 10:00:00 |       2 | 9665014071 |
| 2016-02-06 09:00:00 |       2 | 9662931956 |
| 2016-02-06 08:00:00 |       2 | 9660874138 |
| 2016-02-06 07:00:00 |       2 | 9658624162 |
| 2016-02-06 06:00:00 |       2 | 9656555329 |
| 2016-02-06 05:00:00 |       2 | 9654443169 |
| 2016-02-06 04:00:00 |       2 | 9651362676 |
| 2016-02-06 03:00:00 |       2 | 9648531733 |
| 2016-02-06 02:00:00 |       2 | 9633368883 |
| 2016-02-05 23:00:00 |       2 | 9464826179 |
| 2016-02-05 22:00:00 |       2 | 9363099844 |
| 2016-02-05 21:00:00 |       2 | 9270841166 |
| 2016-02-05 20:00:00 |       2 | 9140988502 |
| 2016-02-05 19:00:00 |       2 | 9022460285 |
| 2016-02-05 18:00:00 |       2 | 8925920799 |
| 2016-02-05 17:00:00 |       2 | 8825711136 |
| 2016-02-05 16:00:00 |       2 | 8802081092 |
| 2016-02-05 15:00:00 |       2 | 8755784419 |
+---------------------+---------+------------+

这并不明显,但可能缺少一些时间。例如。在23到2点钟之间。如果可能的话,我想用0来填补这个缺失的时间。 现在我想选择上周的三小时平均值,但我似乎无法正确查询。我正在尝试并修改此查询一段时间:

select 
    n.n as id, 
    host_id,
    avg(tx),
    insert_time + interval 3 * n.n hour as 'from',
    insert_time + interval 3 * (n.n + 1) hour as 'to'
from (SELECT  0 AS n
          UNION ALL SELECT  1 UNION ALL SELECT  2 UNION ALL SELECT  3
          UNION ALL SELECT  4 UNION ALL SELECT  5 UNION ALL SELECT  6
          UNION ALL SELECT  7 UNION ALL SELECT  8 UNION ALL SELECT  9
          UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12
          UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15
          UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18
          UNION ALL SELECT 19 UNION ALL SELECT 20 UNION ALL SELECT 21
          UNION ALL SELECT 22 UNION ALL SELECT 23 
     ) n 
left join host_daily
     on n.n = hour(insert_time) div 3
where host_id = 2 
  and insert_time > NOW() - INTERVAL 24 HOUR group by n.n;

导致:

+----+---------+-----------------+---------------------+---------------------+
| id | host_id | avg(tx)         | from                | to                  |
+----+---------+-----------------+---------------------+---------------------+
|  4 |       2 | 9672627858.3333 | 2016-02-07 00:00:00 | 2016-02-07 03:00:00 |
|  3 |       2 | 9665011041.6667 | 2016-02-06 18:00:00 | 2016-02-06 21:00:00 |
|  2 |       2 | 9658684543.0000 | 2016-02-06 12:00:00 | 2016-02-06 15:00:00 |
|  1 |       2 | 9651445859.3333 | 2016-02-06 06:00:00 | 2016-02-06 09:00:00 |
|  0 |       2 | 9605672722.3333 | 2016-02-06 00:00:00 | 2016-02-06 03:00:00 |
|  7 |       2 | 9366255729.6667 | 2016-02-06 18:00:00 | 2016-02-06 21:00:00 |
|  6 |       2 | 9029789862.0000 | 2016-02-06 12:00:00 | 2016-02-06 15:00:00 |
|  5 |       2 | 9019970953.0000 | 2016-02-06 06:00:00 | 2016-02-06 09:00:00 |
+----+---------+-----------------+---------------------+---------------------+

有人会如此友善地指出我正确的方向吗?

修改 通过将查询结果编辑为预期结果,从24小时视图返回来维护示例完整性。

1 个答案:

答案 0 :(得分:1)

每次需要将时间缩短到三个小时。假设您每三小时至少有一条记录,您可以使用舍入:

select from_unixtime(floor(unix_timestamp(insert_time)/(60*60*3))*60*60*3) as timestart,
       host_id,
       sum(tx) / 3
from host_daily hd
group by from_unixtime(floor(unix_timestamp(insert_time)/(60*60*3))*60*60*3), hostid
order by 1, 2;

这种假设您希望将缺失值视为0.如果不是,则使用avg(tx)代替。

如果这仍然缺少行,您可以使用所有数据丢失期间所需的任何值添加它们。在这种情况下,你的问题含糊不清。