PHP MySQL Highscore表

时间:2014-02-24 00:20:11

标签: php mysql sql join

我加入3个表来呈现一个用户得分最高的表

我的桌子

game_log:

 ---ID---user_ID---score---time---
 |   1      52      567     10   |
 |   2      53      641     13   |
 |   3      52      465     8    |
 |   4      53      451     14   |
 --------------------------------- 

用户:

 ---ID---name---countyid---
 |   52  Dave      1      |
 |   53  John      2      |
  ------------------------

区:

  ---countyid---countyname---
  |      1    Orange wichit |
  |      2    Orange clemts |
   --------------------------

SQL:

SELECT * FROM game_log 
INNER JOIN users ON game_log.user_ID=users.ID 
INNER JOIN county ON users.countyid=county.countyid 
ORDER BY game_log.score DESC , game_log.time LIMIT 20";

上面的代码给出了我的结果:

Rank---Name--------County------Score---Time
1      John     Orange clemts   641     13
2      Dave     Orange wichit   567     10
3      John     Orange clemts   465     8
4      Dave     Orange wichit   451     14

我的问题是,我希望高分榜能够显示得分最高的前20位用户,而不是20位得分。

像这样:

Rank---Name--------County------Score---Time
1      John     Orange clemts   641     13
2      Dave     Orange wichit   567     10

需要som帮助,不熟悉加入表格; - )

3 个答案:

答案 0 :(得分:2)

此方法将显示前20位用户和每位用户的最高分数,如果他们有多个相同分数的实例,则会显示最早的用户信息(该用户的最低时间值和分数)。 / p>

SELECT *
  FROM game_log gl
 INNER JOIN users u
    ON gl.user_ID = u.ID
 INNER JOIN county c
    ON u.countyid = c.countyid
 WHERE not exists (select 1
          from game_log gl2
         where gl2.user_id = gl.user_id
           and gl2.score > gl.score)
   and not exists (select 1
          from game_log gl2
         where gl2.user_id = gl.user_id
           and gl2.time < gl.time
           and gl2.score = gl.score)
 ORDER BY gl.score DESC, gl.time LIMIT 20;

如果没有这样做,如果前20名中的同一个用户得分相同,则会被列出2次以上,并且使用LIMIT 20就不能找回20个人,因为同一个人会服用从那20个中排出N行。

SQL小提示在这里显示带有平局的数据:http://sqlfiddle.com/#!2/0ac931/5/0

答案 1 :(得分:2)

GROUP BY应该完成这项工作。

SELECT users.ID, users.name, county.countyname, MAX(game_log.score) AS score, game_log.time
FROM game_log
INNER JOIN users ON game_log.user_ID = users.ID
INNER JOIN county ON users.countyid = county.countyid
GROUP BY game_log.user_ID
ORDER BY game_log.score DESC, game_log.time
LIMIT 20;

使用SQL Fiddle尝试。

答案 2 :(得分:1)

我会使用not exists方法执行此操作,以获得每个用户的最高分。查询的其余部分是相同的:

SELECT *
FROM game_log gl INNER JOIN
     users u
     ON gl.user_ID = u.ID INNER JOIN
     county c
     ON u.countyid = c.countyid
WHERE not exists (select 1
                  from game_log gl2
                  where gl2.user_id = gl.user_id and gl2.score > gl.score
                 )
ORDER BY gl.score DESC, gl.time
LIMIT 20;

where子句说“如果同一用户的其他行没有更高的分数,请保留此行”。

另一种方法是使用聚合方法:

SELECT *
FROM (select user_id, max(score) as maxscore
      from game_log gl
      group by user_id
     ) gl INNER JOIN
     users u
     ON gl.user_ID = u.ID INNER JOIN
     county c
     ON u.countyid = c.countyid
ORDER BY gl.maxscore DESC
LIMIT 20;

但是这种方法丢失了有关time的信息。可以包含它,但它会使查询更复杂。