我看过很多关于如何指定时间间隔的帖子。我试图使用它们,但我得到了奇怪的结果。 这是我的表:
select value,time from mysensor9 order by time desc;
+-------+---------------------+
| value | time |
+-------+---------------------+
| 79 | 2016-01-27 22:19:46 |
| 45 | 2016-01-27 22:19:45 |
| 5 | 2016-01-27 22:19:44 |
| 72 | 2016-01-27 22:19:43 |
| 20 | 2016-01-27 22:19:42 |
| 92 | 2016-01-27 22:19:41 |
.....
我已经用一个月的每一秒填充了一张表格。
然后我尝试每隔5分钟/小时/天/月汇总表的数据。当我尝试聚合每天的平均值时,我会进行以下查询:
select AVG(value),time from mysensor9 where time > "2015-12-09" group by UNIX_TIMESTAMP(time) div (3600*24) order by time asc;
结果还可以:
+------------+---------------------+
| AVG(value) | time |
+------------+---------------------+
| 48.7179 | 2015-12-09 02:13:46 |
| 49.4044 | 2015-12-10 02:13:46 |
| 49.5001 | 2015-12-11 02:13:46 |
| 49.4805 | 2015-12-12 02:13:46 |
| 48.9036 | 2015-12-13 02:13:46 |
当我想每1小时间隔聚合时,我会进行以下查询:
select AVG(value),time from mysensor9 where time > "2015-12-09" group by UNIX_TIMESTAMP(time) div (3600) order by time asc;
编辑(小时间隔结果):
+------------+---------------------+
| AVG(value) | time |
+------------+---------------------+
| 49.2355 | 2015-12-09 00:13:46 |
| 48.0028 | 2015-12-09 01:13:46 |
| 49.6316 | 2015-12-09 02:13:46 |
| 47.8449 | 2015-12-09 03:13:46 |
| 49.0166 | 2015-12-09 04:13:46
|
再次结果还可以。但是,当我想使用相同的方法聚合5分钟间隔:
select AVG(value),time from mysensor9 where time > "2015-12-09" group by UNIX_TIMESTAMP(time) div (300) order by time asc;
我明白了:
+------------+---------------------+
| AVG(value) | time |
+------------+---------------------+
| 44.9865 | 2015-12-09 00:13:46 |
| 50.3310 | 2015-12-09 00:15:00 |
| 50.0135 | 2015-12-09 01:13:46 |
| 47.4843 | 2015-12-09 01:15:00 |
| 51.8514 | 2015-12-09 02:13:46 |
为什么会这样?为什么它不会返回这样的东西:
+------------+---------------------+
| AVG(value) | time |
+------------+---------------------+
| 44.9865 | 2015-12-09 00:13:46 |
| 50.3310 | 2015-12-09 00:18:46 |
| 50.0135 | 2015-12-09 00:23:46 |
| 47.4843 | 2015-12-09 00:28:46 |
| 51.8514 | 2015-12-09 00:33:46 |
答案 0 :(得分:1)
当你选择不属于GROUP BY的东西时,mysql会为你选择它(它会选择任何一个分组行)。
您应该选择分组的相同值并将其格式化为日期:
select AVG(value),DATE_FORMAT(FROM_UNIXTIME((UNIX_TIMESTAMP(time) div (300))*300),'%d-%m-%Y %h:%i:%s') as group_time from mysensor9 where time > "2015-12-09" group by UNIX_TIMESTAMP(time) div (300) order by time asc;
你也可以使用MIN()/ MAX()来获得分组行的上端或下端,如果这对你的情况来说是实用的,它似乎更优雅:
select AVG(value),MIN(time) from mysensor9 where time > "2015-12-09" group by UNIX_TIMESTAMP(time) div (300) order by time asc;
另请注意,按上下文选择组中的非组列是MySQL行为,其他一些数据库只会将其声明为语法错误。
答案 1 :(得分:0)
select AVG(value),UNIX_TIMESTAMP(time) div (300) from mysensor9 where time > "2015-12-09" group by UNIX_TIMESTAMP(time) div (300) order by time asc;'
你应该使用这样的组。