简体   繁体   English

MySQL获取一组每x分钟的列的平均值和总和

[英]MySQL get the average and sum of a columns for each x minutes of a group

I tried multiple hours to figure out a query for this but I had no luck.我尝试了几个小时来找出对此的查询,但我没有运气。 I don't even know if it is possible with just one query.我什至不知道仅一个查询是否可行。

I have a table like this我有一张这样的桌子

id - server_id - players_online - performance - timestamp

This table includes about one record for each server every 5-10 minutes.该表每 5-10 分钟包含每个服务器的大约一条记录。 The thing is, I wanna get the average performance and the sum of players_online per 20 minute interval but as the same server can occur multiple times within these 20 minutes it can corrupt the final result that I want:问题是,我想获得每 20 分钟间隔的平均性能和 player_online 的总和,但由于同一服务器可能在这 20 分钟内出现多次,因此可能会破坏我想要的最终结果:

  1. group by 20 min interval按 20 分钟间隔分组
  2. only keep one result per server_id per 20 min interval每 20 分钟间隔为每个 server_id 仅保留一个结果
  3. get the average performance and sum of players_online of all servers per 20 min interval获取所有服务器每 20 分钟间隔的平均性能和 player_online 总和

With ROUND(timestamp/(20*60)) I can easily group by the 20 min interval, but how do I proceed.使用 ROUND(timestamp/(20*60)) 我可以轻松地按 20 分钟间隔分组,但我该如何进行。 How would you write query?你会怎么写查询?

The query I tried to so far:到目前为止我尝试的查询:

SELECT avg(performance) as performance, sum(playersOnline) as playersOnline, timestamp
    FROM stats_server
    GROUP BY ROUND(timestamp/(1200))

Example Data: http://www.mediafire.com/download/z629q3g38qhr46h/stats_server.sql.gz示例数据: http : //www.mediafire.com/download/z629q3g38qhr46h/stats_server.sql.gz

Result (average/sum from servers for this time) :结果(这次来自服务器的平均值/总和):

timestamp     | performance | online players
1404757200000 | 93          | 125
1404758400000 | 92          | 120
1404759600000 | 96          | 133
1404759800000 | 93          | 168
1404751000000 | 88          | 122
1404751200000 | 94          | 134

SOLUTION:解决方案:

SELECT min20 * 1200 AS timestamp, AVG( performance ) AS performance, SUM( players ) AS playersOnline
        FROM (
            SELECT serverID, FLOOR( UNIX_TIMESTAMP( timestamp ) / 1200 ) AS min20, AVG( performance ) AS performance, AVG( playersOnline ) AS players
            FROM stats_server
            GROUP BY min20, serverID
        ) tmp
        GROUP BY min20
        ORDER BY timestamp

Your problem lies with your information design.你的问题在于你的信息设计。 If there are 10 people online at a moment and 10 poeple online a moment later, you cannot say if there were 10 or 20 people online.如果一时有10人在线,一会后有10人在线,你不能说是10人还是20人在线。 It could have been the same 10 people like the moment before or 10 new people.可能是和之前一样的 10 个人,也可能是 10 个新人。

If you want to get the exact number of people online, you have to save information that help to distinguish your users, like IP-Adresses.如果您想获得准确的在线人数,您必须保存有助于区分您的用户的信息,例如 IP 地址。

Based on your records, the only logical thing would be to fetch the maximum of people online, say根据您的记录,唯一合乎逻辑的事情是在网上获取最多的人,例如

max(playersOnline)

which is at least a lower bound for the sum of players online.这至少是在线玩家总和的下限。

SELECT min20 * 1200 AS timestamp, AVG( performance ) AS performance, SUM( players ) AS playersOnline FROM ( SELECT serverID, FLOOR( UNIX_TIMESTAMP( timestamp ) / 1200 ) AS min20, AVG( performance ) AS performance, AVG( playersOnline ) AS players FROM stats_server GROUP BY min20, serverID ) tmp GROUP BY min20 ORDER BY timestamp

If you are using MySql or SQL and the timestamp is a standard unix timestamp you are best formatting the timestamp to a date / time format to then group the results.如果您使用的是 MySql 或 SQL 并且时间戳是标准的 unix 时间戳,则最好将时间戳格式化为日期/时间格式,然后对结果进行分组。

have a look at http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format看看http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format

so for example you could change the timestamp to be DD MM YYYY HH:MM and group by that例如,您可以将时间戳更改为 DD MM YYYY HH:MM 并按此分组

GROUP BY server_id, DATE_FORMAT(timestamp, '%W %M %Y %H:%S')

EDIT: Think you need to group by server_id first编辑:认为您需要先按 server_id 分组

EDIT 2: Try the following - can't really test as the timestamps are out when using now()编辑 2:尝试以下操作 - 无法真正测试,因为使用 now() 时时间戳已过期

SELECT serverID, avg(performance), sum(playersOnline), DATE_FORMAT(timestamp, '%W %M %Y %H:%S') FROM `stats_server` where timestamp > now()-1200 group by ROUND(timestamp/(1200)), serverID order by serverID, ROUND(timestamp/(1200)) asc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM