使用 GROUP BY 时选择特定行

joh*_*tke 3 mysql sql

我有以下 SQL 表,用于跟踪用户在特定时间点的分数。一个用户每天可以有多个分数。

+-------+------------+-------+-----+
| user  | date       | score | ... |
+-------+------------+-------+-----+
| bob   | 2014-04-19 | 100   | ... |
| mary  | 2014-04-19 | 100   | ... |
| alice | 2014-04-20 | 100   | ... |
| bob   | 2014-04-20 | 110   | ... |
| bob   | 2014-04-20 | 125   | ... |
| mary  | 2014-04-20 | 105   | ... |
| bob   | 2014-04-21 | 115   | ... |
+-------+------------+-------+-----+
Run Code Online (Sandbox Code Playgroud)

给定一个特定用户(比方说bob),我如何生成每个用户分数的报告,但只使用每天提交的最高分数?(获得最高分的特定行也很重要,而不仅仅是最高分)

SELECT * FROM `user_score` WHERE `user` = 'bob' GROUP BY `date`
Run Code Online (Sandbox Code Playgroud)

是我正在构建的基本查询。结果集如下:

+-------+------------+-------+-----+
| user  | date       | score | ... |
+-------+------------+-------+-----+
| bob   | 2014-04-19 | 100   | ... |
| bob   | 2014-04-20 | 110   | ... |
| bob   | 2014-04-21 | 115   | ... |
+-------+------------+-------+-----+
Run Code Online (Sandbox Code Playgroud)

bob缺少125from的较高分数2014-04-20。我试着用MAX(score)

SELECT *, MAX(score)  FROM `user_score` WHERE `user` = 'bob' GROUP BY `date`
Run Code Online (Sandbox Code Playgroud)

返回当天的最高分,但不返回得分最高的行。该行的其他列值很重要,

+-------+------------+-------+-----+------------+
| user  | date       | score | ... | max(score) |
+-------+------------+-------+-----+------------+
| bob   | 2014-04-19 | 100   | ... | 100        |
| bob   | 2014-04-20 | 110   | ... | 125        |
| bob   | 2014-04-21 | 115   | ... | 110        |
+-------+------------+-------+-----+------------+
Run Code Online (Sandbox Code Playgroud)

最后,我试过了

SELECT *, MAX(score)  FROM `user_score` WHERE `user` = 'bob' AND score = MAX(score) GROUP BY `date`
Run Code Online (Sandbox Code Playgroud)

但这会导致GROUP BY.

编辑:

SQLFiddle:http ://sqlfiddle.com/#!2/ee6a2

Gor*_*off 5

如果您想要所有字段,MySQL 中最简单(也是最快)的方法是使用not exists

SELECT *
FROM `user_score` us
WHERE `user` = 'bob' AND
      NOT EXISTS (SELECT 1
                  FROM user_score us2
                  WHERE us2.`user` = us.`user` AND
                        us2.date = us.date AND
                        us2.score > us.score
                 );
Run Code Online (Sandbox Code Playgroud)

这似乎是一种奇怪的方法。而且,我承认确实如此。它所做的非常简单:“从user_score没有更高分数的地方(对于 Bob)获取 Bob 的所有行”。这相当于获得最高分的行。使用索引user_score(name, score),这可能是做你想做的最有效的方法。