查找用户的最高分数和相关详细信息
我有一个表,用户在其中存储分数和有关该分数的其他信息(例如分数注释或所用时间等)。我想要一个 mysql 查询来查找每个用户的个人最佳分数及其相关的注释和时间等。
我尝试使用的是这样的:
SELECT *, MAX(score) FROM table GROUP BY (user)
问题是虽然您可以从该查询 [MAX(score)] 中额外获得用户的个人最佳成绩,但返回的注释和时间等与最高分数无关,而是与不同的分数相关联(特别是 * 中包含的分数)。有没有办法编写一个查询来选择我想要的内容?或者我必须在 PhP 中手动完成?
I have a table in which users store scores and other information about said score (for example notes on score, or time taken etc). I want a mysql query that finds each users personal best score and it's associated notes and time etc.
What I have tried to use is something like this:
SELECT *, MAX(score) FROM table GROUP BY (user)
The problem with this is that whilst you can extra the users personal best from that query [MAX(score)], the returned notes and times etc are not associated with the maximum score, but a different score (specifically the one contained in *). Is there a way I can write a query that selects what I want? Or will I have to do it manually in PhP?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我假设您只希望每个玩家获得一个结果,即使他们多次获得相同的最高分。我还假设您希望每个玩家第一次获得个人最佳成绩,以防出现重复。
有几种方法可以做到这一点。这是一种 MySQL 特定的方法:
这是一种使用普通 SQL 的更通用的方法:
结果:
测试数据 我用来测试这个:
I'm assuming that you only want one result per player, even if they have scored the same maximum score more than once. I am also assuming that you want each player's first time that they got their personal best in the case that there are repeats.
There's a few ways of doing this. Here's a way that is MySQL specific:
Here's a more general way that uses ordinary SQL:
Result:
Test data I used to test this:
您可以使用子查询进行连接,如下例所示:
上述查询可以解释如下。它以:
...这本身显然会列出表的所有内容。目标是仅保留代表特定用户最高分数的行。因此,如果我们有以下数据:
...我们只想保留“note c”和“note e”行。
要找到我们想要保留的行,我们可以简单地使用:
请注意,我们无法从上面的查询中获取 Notes 属性,因为正如您已经注意到的,对于未使用 聚合函数,如 MAX() 或不是
GROUP BY
子句的一部分。要进一步阅读此主题,您可能需要检查:现在我们只需要保留第一个查询中与第二个查询匹配的行。我们可以使用
INNER JOIN
来做到这一点:子查询的名称为
sub_t
。它是所有具有个人最好成绩的用户的集合。JOIN
的ON
子句将限制应用于相关字段。请记住,我们只想保留属于此子查询的行。You can join with a sub query, as in the following example:
The above query can be explained as follows. It starts with:
... This by itself will obviously list all the contents of the table. The goal is to keep only the rows that represent a maximum score of a particular user. Therefore if we had the data below:
...We would have wanted to keep just the "note c" and "note e" rows.
To find the rows that we want to keep, we can simply use:
Note that we cannot get the notes attribute from the above query, because as you had already noticed, you would not get the expected results for fields not aggregated with an aggregate function, like
MAX()
or not part of theGROUP BY
clause. For further reading on this topic, you may want to check:Now we only need to keep the rows from the first query that match the second query. We can do this with an
INNER JOIN
:The sub query is given the name
sub_t
. It is the set of all the users with the personal best score. TheON
clause of theJOIN
applies the restriction to the relevant fields. Remember that we only want to keep rows that are part of this subquery.旁注:指定字段比使用
SELECT *
更好Side note: It is better to specify the fields than use
SELECT *