选择每位玩家的最佳得分

Art*_*uro 1 mysql select group-by max sql-order-by

我有一个名为表Scores包含列:id,player_id,value1,value2,value3date.

该表具有以下内容:

+------+-----------+--------+--------+--------+------------+
|  id  | player_id | value1 | value2 | value3 |    date    |
+------+-----------+--------+--------+--------+------------+
|   1  |     1     |   10   |    0   |   0    | 2012-08-02 |
+------+-----------+--------+--------+--------+------------+
|   2  |     2     |   15   |    1   |   0    | 2012-08-03 |
+------+-----------+--------+--------+--------+------------+
|   3  |     3     |    9   |    0   |   0    | 2012-08-04 |
+------+-----------+--------+--------+--------+------------+
|   4  |     1     |   11   |    0   |   0    | 2012-08-05 |
+------+-----------+--------+--------+--------+------------+
|   5  |     2     |   16   |    2   |   0    | 2012-08-06 |
+------+-----------+--------+--------+--------+------------+
|   6  |     2     |   15   |    0   |   0    | 2012-08-07 |
+------+-----------+--------+--------+--------+------------+
Run Code Online (Sandbox Code Playgroud)

我正在尝试获取一个查询,该查询返回按"value1,value2,value3"中的值排序的每个玩家的最佳高分.Value1是具有更高重要性,value2中等重要性和value3次要重要性的字段,例如:

value1 = 15                              value1 = 15
value2 = 1       is greater than ->      value2 = 0
value3 = 0                               value3 = 1
Run Code Online (Sandbox Code Playgroud)

我需要的查询的预期结果是:

+------+-----------+--------+--------+--------+------------+
|  id  | player_id | value1 | value2 | value3 |    date    |
+------+-----------+--------+--------+--------+------------+
|   5  |     2     |   16   |    2   |   0    | 2012-08-06 |
+------+-----------+--------+--------+--------+------------+
|   4  |     1     |   11   |    0   |   0    | 2012-08-05 |
+------+-----------+--------+--------+--------+------------+
|   3  |     3     |    9   |    0   |   0    | 2012-08-04 |
+------+-----------+--------+--------+--------+------------+
Run Code Online (Sandbox Code Playgroud)

我正在尝试MAX,DISTINCT,GROUP BY和子查询,但我没有得到正确的结果.基本上它是下一个查询,但选择每个"组"的第一行:

SELECT id, player_id, value1, value2, value3
   FROM scores
   ORDER BY value1 DESC, value2 DESC, value3 DESC
Run Code Online (Sandbox Code Playgroud)

------ 编辑1 -------

eggyal的答案很好,但也许表现不太好.我需要针对大型数据库对他的解决方案进行基准测试,以检查响

我有一个想法(和可能的解决方案).解决方案包括添加新的布尔列,该表示该得分是否是该玩家的最佳得分.这样我需要检查当我将新分数添加到数据库中时,新分数是否优于该分区的最佳旧分数,如果是,我需要在旧的最佳分数中将该标记标记为假,并且在新的分数.这给了我一种方法来直接检索每个玩家的最佳得分(像简单的查询一样SELECT ... FROM .... ORDER BY).

------ 编辑2 -------

weicap的答案是最快的解决方案.我不知道为什么,但他的查询比eggyal的查询快两倍.

------ 编辑3 -------我错了,如果查询先前被缓存,weicap的查询会更快,如果查询不是十秒或更长时间.在变化中,weicap的答案总是需要300-400ms而不是80.000行.

egg*_*yal 5

对于每个value,您可以获得groupwise最大值:

SELECT * FROM Scores NATURAL JOIN (
  SELECT player_id, value1, value2, MAX(value3) value3 FROM Scores NATURAL JOIN (
  SELECT player_id, value1, MAX(value2) value2         FROM Scores NATURAL JOIN (
  SELECT player_id, MAX(value1) value1                 FROM Scores
    GROUP BY player_id) t
    GROUP BY player_id) t
    GROUP BY player_id) t
ORDER BY value1 DESC, value2 DESC, value3 DESC
Run Code Online (Sandbox Code Playgroud)

sqlfiddle上看到它.