使用特定条件查找最大值,并检查同一组是否存在较高/较低值或任何值

时间:2019-03-22 19:20:40

标签: php mysql sql

我正在尝试获取游戏...并且用户和信息的最高分数是高于或低于用户最高值的(其他玩家的得分)。我会解释情况。

在激活游戏的情况下,用户应获得自己的游戏以及每个游戏的最高得分。这对于JOINGROUP BY来说很好用,但是我不知道如何获得信息,是否存在更多的得分,并且得分高于或低于用户的最高得分。

表1:scores

+----+--------+------+--------+-------+
| id | gameID | game | player | score |
+----+--------+------+--------+-------+
|  1 |      1 | pang | lea    |    50 |
|  2 |      1 | pang | lea    |    60 |
|  3 |      1 | pang | paola  |    70 |
|  4 |      2 | pong | lea    |   100 |
|  5 |      2 | pong | paola  |    90 |
+----+--------+------+--------+-------+

表2:games

+----+------+--------+
| id | name | active |
+----+------+--------+
|  1 | pang | yes    |
|  2 | pong | yes    |
|  3 | pung | yes    |
+----+------+--------+

代码:

$loggedUser = 'lea';
$sql = 
    "
SELECT s.gameID
     , s.game
     , COUNT(s.id) c
     , MAX(s.score) Max
  FROM scores s
 RIGHT 
  JOIN games g
    ON s.gameID = g.id
 WHERE g.active = 'yes' 
   AND s.player = '$loggedUser'
 GROUP 
    BY s.gameID 
 ORDER 
    BY c
";

输出应如下所示:

  

Hello Lea,您的最高得分:

     

庞打2次,最高得分60分(最高得分为70分)。...

     

乒乓球播放次数x 1,100分,您的得分更高。...

1 个答案:

答案 0 :(得分:0)

在MySQL 8.0中,您可以使用窗口函数执行以下操作:

  • 对每个游戏的玩家得分进行排名:ROW_NUMBER() OVER(PARTITION BY player, game ORDER BY score DESC)
  • 计算一个玩家玩过多少次游戏:COUNT(*) OVER(PARTITION BY player, game)
  • 计算给定游戏在所有玩家中的最高得分:MAX(score) OVER(PARTITION BY game ORDER BY score DESC)

考虑以下查询:

SELECT game_name, cnt games_played, score max_score, top_score
FROM (
    SELECT
        g.name game_name,
        s.player,
        s.score,
        ROW_NUMBER() OVER(PARTITION BY player, game ORDER BY score DESC) rn,
        COUNT(*) OVER(PARTITION BY player, game) cnt,
        MAX(score) OVER(PARTITION BY game ORDER BY score DESC) top_score
    FROM scores s
    INNER JOIN games g ON g.id = s.gameID AND g.active = 'yes'
) x WHERE rn = 1 AND player = 'lea';

this db fiddle 中使用示例数据,查询将产生:

| game_name | games_played | max_score | top_score |
| --------- | ------------ | --------- | --------- |
| pang      | 2            | 60        | 70        |
| pong      | 1            | 100       | 100       |

在MySQL的早期版本中,一种解决方案是使用聚合子查询来计算所有玩家中每个游戏的最高得分,并使用主要聚合查询JOIN来计算得分:

SELECT g.name game_name, COUNT(*) games_played, MAX(s.score) max_score, ts.top_score
FROM  scores s
INNER JOIN games g 
    ON g.id = s.gameID AND g.active = 'yes'
INNER JOIN (SELECT gameID, MAX(score) top_score FROM scores GROUP BY gameID) ts 
    ON s.gameID = ts.gameID
WHERE s.player = 'lea'
GROUP BY s.player, g.id, g.name;

Demo on DB Fiddle