Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:为用户获得最高分数_Sql_Mysql - Fatal编程技术网

MySQL:为用户获得最高分数

MySQL:为用户获得最高分数,sql,mysql,Sql,Mysql,我有下表的高分 id gameid userid name score date 1 38 2345 A 100 2009-07-23 16:45:01 2 39 2345 A 500 2009-07-20 16:45:01 3 31 2345 A

我有下表的高分

id      gameid      userid      name      score      date
1       38          2345        A         100        2009-07-23 16:45:01
2       39          2345        A         500        2009-07-20 16:45:01
3       31          2345        A         100        2009-07-20 16:45:01
4       38          2345        A         200        2009-10-20 16:45:01
5       38          2345        A         50         2009-07-20 16:45:01
6       32          2345        A         120        2009-07-20 16:45:01
7       32          2345        A         100        2009-07-20 16:45:01
在上面的结构中,用户可以多次玩游戏,但我想显示特定用户玩的游戏。所以在游戏播放部分,我不能显示多个游戏。因此,这个概念应该类似于如果一个用户玩了一个游戏3次,那么应该显示所有游戏中得分最高的游戏

我想要的结果数据如下:

id      gameid      userid      name      score      date
2       39          2345        A         500        2009-07-20 16:45:01
3       31          2345        A         100        2009-07-20 16:45:01
4       38          2345        A         200        2009-10-20 16:45:01
6       32          2345        A         120        2009-07-20 16:45:01
我尝试了以下查询,但结果不正确:

SELECT id, 
       gameid, 
       userid, 
       date, 
       MAX(score) AS score 
  FROM highscores
 WHERE userid='2345' 
GROUP BY gameid 
请告诉我这个问题的答案是什么


谢谢

当存在GROUP BY子句时,SELECT中的每个字段必须是GROUP BY子句中的一个字段,或者是代码中的一个组函数,如MAX、SUM、AVG等,userid在技术上违反了这一点,但以一种非常无害的方式,您可以使您的代码在技术上符合SQL标准,符合一组gameid,userid;id和date字段的冲突更为严重-一组中会有许多id和date,并且您不会告诉如何从该组中生成一个值,而MySQL会或多或少地随机选择一个值,更严格的SQL引擎可能会更有效地给您一个错误


我知道您需要与给定分组的最大分数对应的id和日期,但这在代码中并不明确。您将需要一个子选择或自联接来使其显式化

需求有点模糊/混乱,但这样的东西能满足需求吗? 故意添加各种可能感兴趣的骨料

SELECT gameid, 
       MIN(date) AS FirstTime, 
       MAX(date) AS LastTime,
       MAX(score) AS TOPscore.
       COUNT(*)  AS NbOfTimesPlayed 
FROM highscores
WHERE userid='2345' 
GROUP BY gameid
-- ORDER BY COUNT(*) DESC -- for ex. to have games played most at top
编辑:关于将id列添加到选择列表的新问题 简单的回答是:不,不能添加id,不能在这个特定的构造中添加id。进一步阅读,了解为什么,如果目的是获得得分最高的游戏id,可以使用子查询修改查询以实现这一点

正如Alex M在本页中所解释的,SELECT列表中引用的所有列名以及未在聚合函数MAX、MIN、AVG、COUNT等上下文中使用的列名必须包含在ORDER by子句中。SQL语言使用此规则的原因很简单,就是在收集结果列表的信息时,SQL可能会遇到SELECT中列出的此类列的多个值,而不是GROUP BY,并且不知道如何处理它;SQL标准没有使用这些额外的行/值做任何事情(可能有用,但也可能愚蠢),而是指定了一条错误消息,以便用户可以修改查询并明确表示其目标

在我们的特定情况下,我们可以在SELECT中添加id,也可以在GROUP BY列表中添加id,但在这样做时,进行聚合的分组将有所不同:结果列表将包括尽可能多的行,因为我们有id+gameid组合。每一行的聚合值将仅基于表中的记录,其中id和gameid具有相应的值,假设id是表中的PK,我们将在每个聚合中得到一行,这使得MAX和类似的值变得毫无意义

通过子查询可以包含id以及可能与得分最高的游戏对应的其他列。其思想是,子查询选择给定group by中得分最高的游戏,主查询选择该行中的任何列,即使FIED不在子查询的group by构造中。顺便说一句,在这一页上要赞扬rexem首先显示了这种类型的查询

SELECT H.id, 
       H.gameid, 
       H.userid, 
       H.name,
       H.score,
       H.date        
FROM highscores H
JOIN (
  SELECT M.gameid, hs.userid, MAX(hs.score) MaxScoreByGameUser
  FROM highscores H2
  GROUP BY H2.gameid, H2.userid
) AS M  
   ON M.gameid = H.gameid 
      AND M.userid = H.userid
      AND M.MaxScoreByGameUser = H.score
WHERE H.userid='2345' 
关于上述问题的几点重要评论

重复:如果用户玩了几个达到相同hi分数的游戏,查询将产生那么多行。 子查询的分组依据可能需要根据查询的不同用途进行更改。如果我们不想在每个用户的基础上搜索游戏的hi分数,而是想要绝对hi分数,那么我们需要将userid从组中排除,这就是为什么我用一个长而显式的名称命名MAX的别名 userid='2345'可以添加到子查询的[now缺席]WHERE子句中,以提高效率,除非MySQL的优化器非常智能,目前所有游戏+用户组合的所有hi分数都得到计算,因此我们只需要用户'2345'的hi分数;下侧复制;解决方案变量。 有几种方法可以解决上述问题,但这些方法似乎超出了[现在相当长]对分组结构的解释范围。

使用:

SELECT t.id, 
       t.gameid, 
       t.userid, 
       t.name,
       t.score,
       t.date        
  FROM HIGHSCORES t
  JOIN (SELECT hs.gameid, 
               hs.userid,
               MAX(hs.score) 'max_score'
          FROM HIGHSCORES hs
      GROUP BY hs.gameid, hs.userid) mhs ON mhs.gameid = t.gameid
                                        AND mhs.userid = t.userid
                                        AND mhs.max_score = t.score
 WHERE t.userid = '2345' 

如果同一游戏和用户有2+项记录,且得分相同,那么平局打破者的处理情况如何?最近的日期?@rexem:在这种情况下,它将只返回2条记录中的1条。@Prashant:是的,但基于什么条件?@Prasshant:如果有2个以上的用户id、游戏id和分数组合-你用什么打破平局?我们可以在这个查询中包括id字段吗。当我把它包括进来的时候,它没有给出正确的id???@Prashant:它不会是正确的id,因为你是一个群体
按gameid ping。因此,id可能会包含在测试过程中找到的最后一条序号记录grouping@Kevin佩诺,谢谢你的快速回复@Prashant,我编辑了回复,并用一个子查询对为什么不能[在这个构造中]添加id以及如何添加id做了更详细的解释。