从 table 中获取用户的最高分

Get user's highest score from a table

我觉得这是一个非常简单的问题,但也许我现在脑子放屁,似乎不知道该怎么做。

我有一个 MySQL table 结构,如下所示

+---------------------------------------------------+
| id |     date     |  score  |  speed  |  user_id  |
+---------------------------------------------------+
|  1 |  2016-11-17  |  2      | 133291  |     17    |
|  2 |  2016-11-17  |  6      | 82247   |     17    |
|  3 |  2016-11-17  |  6      | 21852   |     17    |
|  4 |  2016-11-17  |  1      | 109338  |     17    |
|  5 |  2016-11-17  |  7      | 64762   |     61    |
|  6 |  2016-11-17  |  8      | 49434   |     61    |

现在我可以通过这样做获得特定用户的最佳性能

SELECT * 
FROM performance 
WHERE user_id = 17 AND date = '2016-11-17'
ORDER BY score desc,speed asc LIMIT 1

这应该 return ID = 3 的行。现在我想要的是一个查询 运行 能够 return 每个唯一的 1 这样的行 user_id 在 table 中。所以最终的结果会是这样的

+---------------------------------------------------+
| id |     date     |  score  |  speed  |  user_id  |
+---------------------------------------------------+
|  3 |  2016-11-17  |  6      | 21852   |     17    |
|  6 |  2016-11-17  |  8      | 49434   |     61    |

此外,我能否在同一个查询中提出另一个问题,根据相同的排序标准(得分降序、速度升序)进一步对最终结果 table 进行排序。谢谢

对于mysql

您可以尝试在子选择中使用双选并按

分组
  select * from    performance
  where (user_id, score,speed ) in (

            SELECT user_id, max_score, max(speed)
            FROM performance 
            WHERE (user_id, score) in (select user_id, max(score) max_score
                                       from performance 
                                       group by user_id)
            group by user_id, max_score
  );

很容易使用变量来模拟row_number() over (partition by Order by)

解释:

  1. 首先在子查询中创建两个变量。
  2. user_id 排序,因此当用户更改 @rn 时重置为 1
  3. score 降序排列,speed 升序排列,这样每一行都会有一个 row_number,而你想要的总是会有 rn = 1
  4. @rn := 你为每一行改变 @rn
    • 如果您有新的 user_id,则 @rn 设置为 1
    • 否则@rn设置为@rn+1

SQL Fiddle Demo

SELECT `id`, `date`, `score`, `speed`, `user_id`
FROM (
        SELECT *,
               @rn := if(@user_id = `user_id`, 
                         @rn + 1 , 
                         if(@user_id := `user_id`,1,1)
                        ) as rn           
        FROM Table1
        CROSS JOIN (SELECT @user_id := 0, @rn := 0) as param
        WHERE date = '2016-11-17' 
        ORDER BY `user_id`, `score` desc, `speed` asc
     ) T
where T.rn =1      

输出

使用相关子查询的简单方法:

select p.* 
from performance p
where p.date = '2016-11-17' and
      p.id = (select p2.id
              from performance p2
              where p2.user_id = p.user_id and p2.date = p.date
              order by score desc, speed asc
              limit 1
             );

这应该可以利用 performance(date, user_id, score, speed) 上的索引。