【问题标题】:SQL select 3 hour avgSQL 选择 3 小时平均
【发布时间】:2016-02-06 12:54:55
【问题描述】:

我得到了这张桌子:

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 小时视图返回。

【问题讨论】:

  • 平均 3 小时意味着 (1,2,3) - (2,3,4) - (3,4,5) - (4,5,6) ... (21,22,23) ?您能否在该示例数据中包含您的预期结果?请阅读stackoverflow.com/help/how-to-ask这里是START的好地方
  • 3 hours avg 表示我想选择所选周的前三个小时返回。在示例中,它将是从 15:00 到 17:00,并将 tx[0] 8755784419 + tx[1] 8802081092 + tx[2] 8825711136 的平均值作为一行返回,下一行从 18:00 到 20 开始:00 等等。可能正如你现在描述的那样,我完成了打字。
  • 在最新的MariaDB 中,您可以用魔术表替换所有UNIONseq_0_to_23

标签: mysql datetime mariadb


【解决方案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)

如果这仍然缺少行,您可以在缺少 所有 数据的期间将它们添加为您想要的任何值。您的问题对于在这种情况下包含什么内容含糊不清。

【讨论】:

  • 我想将缺失值视为 0,因为它们是机器中断。如果机器将在 13:45 旋转,则将有 14:00 的平均值。抱歉不清楚,我会试试你的建议。
  • 嘿,感谢您的解决方案。但是您应该避免使用硬编码的分隔符。不保证有 2 个元素与第一个时间戳分组。澄清示例pastebin.com/raw/0HNqPrVX
猜你喜欢
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
相关资源
最近更新 更多