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

时间:2014-07-07 18:12:27

标签: php mysql sql

我尝试了几个小时来找出这个问题,但我没有运气。我甚至不知道只有一个查询是否可行。

我有一张这样的表

id - server_id - players_online - performance - timestamp

此表包含每5-10分钟一个服务器的大约一条记录。 问题是,我想获得平均性能和每20分钟间隔的players_online之和,但由于同一服务器可以在这20分钟内多次出现,它可能会破坏我想要的最终结果:

  1. 分组间隔20分钟
  2. 每20分钟间隔只为每个server_id保留一个结果
  3. 获取每20分钟间隔的所有服务器的平均性能和players_online之和
  4. 使用ROUND(时间戳/(20 * 60))我可以轻松地按20分钟间隔分组,但我该如何进行。你会怎么写查询?

    到目前为止我试过的查询:

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

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

    结果(此时服务器的平均值/总和):

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

    解决方案:

    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
    

3 个答案:

答案 0 :(得分:1)

您的问题在于您的信息设计。如果片刻在线有10个人,片刻后有10个人在线,你不能说是否有10或20个人在线。它可能是像前一样的10个人或10个新人。

如果您想获得在线人数,您必须保存有助于区分用户的信息,例如IP地址。

根据您的记录,唯一合乎逻辑的事情就是在线获取最多的人,比如说

max(playersOnline)

至少是在线玩家总数的下限。

答案 1 :(得分:0)

如果您使用的是MySql或SQL且时间戳是标准的unix时间戳,则最好将时间戳格式化为日期/时间格式,然后对结果进行分组。

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

因此,例如,您可以将时间戳更改为DD MM YYYY HH:MM和分组

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

编辑:认为您需要先按server_id进行分组

编辑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

答案 2 :(得分:0)

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