【问题标题】:Get max user scores from hourly sums从每小时总和中获取最大用户分数
【发布时间】:2012-12-14 02:13:17
【问题描述】:

我有一个 MySql 表,其中包含如下示例数据:

+---------+---------+--------+---------------------+
|      id | user_id | scores |          created_at |
+---------+---------+--------+---------------------+
|       1 |       1 |     10 | 2012-12-14 02:40:37 |
|       2 |       1 |     20 | 2012-12-14 02:55:54 |
|       3 |       1 |     10 | 2012-12-14 01:17:21 |
|       4 |       2 |     30 | 2012-12-13 01:54:47 |
|       5 |       2 |     55 | 2012-12-15 00:34:39 |
|       6 |       2 |     10 | 2012-12-14 00:20:21 |
+---------+---------+--------+---------------------+

我需要查询它,以便按用户和每小时计算分数。这里的一小时假定为created_at,跳过了分钟和秒(04:00:00 到 04:59:59 等)。所以是这样的:

+---------+--------+---------------------+
| user_id | scores |          created_at |
+---------+--------+---------------------+
|       1 |     30 | 2012-12-14 02:00:00 |
|       1 |     10 | 2012-12-14 01:00:00 |
|       2 |     30 | 2012-12-13 01:00:00 |
|       2 |     55 | 2012-12-15 00:00:00 |
|       2 |     10 | 2012-12-14 00:00:00 |
+---------+--------+---------------------+

在此示例数据中,只有第一个用户在一小时内(2012 年 12 月 14 日 02:00:00)玩了不止一次 - 所以他在那一小时内的得分被总结了。

从总分中,我只需要每个用户的最高分(创建排名)。所以最终的预期结果应该是:

+---------+---------------------+---------------------+
| user_id | top_scores_per_hour |                hour |
+---------+---------------------+---------------------+
|       1 |                  30 | 2012-12-14 02:00:00 |
|       2 |                  55 | 2012-12-15 00:00:00 |
+---------+---------------------+---------------------+

我有一个想法如何做这部分...我可以处理数据库之外的其余部分,但我真的很想知道 - 我怎么能用 SQL 查询这个?

【问题讨论】:

    标签: mysql sql group-by sum


    【解决方案1】:
    SELECT a.user_id,
           a.totalScores top_scores_per_hour,
           a.newTime hour
    FROM
        (
          SELECT  user_id, 
                  SUM(Scores) totalScores, 
                  DATE_Format(created_at, '%Y-%m-%d %H:00:00') newTime
          FROM    TableName 
          GROUP BY user_id, DATE_Format(created_at, '%y-%m-%d %H:00:00')
        ) a INNER JOIN 
        (
          SELECT  user_id, 
                  max(DATE_Format(created_at, '%Y-%m-%d %H:00:00')) newTime
          FROM    TableName 
          GROUP BY user_ID
        ) b ON a.user_ID = b.user_ID AND
               a.newTime = b.newTime
    

    输出

    ╔═════════╦═════════════════════╦═════════════════════╗
    ║ USER_ID ║ TOP_SCORES_PER_HOUR ║        HOUR         ║
    ╠═════════╬═════════════════════╬═════════════════════╣
    ║       1 ║                  30 ║ 2012-12-14 02:00:00 ║
    ║       2 ║                  55 ║ 2012-12-15 00:00:00 ║
    ╚═════════╩═════════════════════╩═════════════════════╝
    

    【讨论】:

    • 对不起,我在使用更多数据后不接受。它总是选择得分总和的最新小时,而不是选择得分总和最高的小时。
    • 评论是我需要的实际答案。如果可以的话,我会接受它,谢谢。
    【解决方案2】:

    试试这个:

    SELECT user_id, score, createdDate 
    FROM (SELECT user_id, SUM(scores) score, DATE_FORMAT(created_at, '%Y-%m-%d %H:00:00') createdDate 
          FROM tablename 
          GROUP BY user_id, createdDate
          ORDER BY user_id, score DESC) AS A 
    GROUP BY user_id
    

    【讨论】:

    • 这也有效,而且看起来更简单。然而,我担心安全 - 结果是否总是符合预期。因为不能保证,非分组列将始终从最后一组行开始使用,对吗?我选择了其他答案,但这一个也很好。谢谢。
    【解决方案3】:

    怎么样

    Select user_id, Max(totalHouirlyScore) TopHourlyScore
    From (Select user_id, Sum(scores) totalHouirlyScore
          From tablename
          Group By user_id, 
                DateFormat(created_at, '%y%m%d%H')) Z
    

    【讨论】:

    • 问题是我还需要小时列:(
    • 你不能把DateFormat(created_at, '%y%m%d%H')) Z 添加到选择列的列表中吗?
    • 格雷格 - 不。除了运行这个查询,即使没有小时列也不会返回预期的数据。
    猜你喜欢
    • 1970-01-01
    • 2021-01-17
    • 2016-11-23
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多