查找具有特定标准的最大值并检查同一组是不是有更高/更低或任何值

Posted

技术标签:

【中文标题】查找具有特定标准的最大值并检查同一组是不是有更高/更低或任何值【英文标题】:Find max value with specific criteria and check if there is higher/lower or any value for same group查找具有特定标准的最大值并检查同一组是否有更高/更低或任何值 【发布时间】:2019-03-22 19:20:39 【问题描述】:

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

用户应该在游戏处于活动状态时获得他的游戏和每个游戏的最高分数。这适用于JOINGROUP BY,但我不知道如何获取信息是否有更多分数,它们是否高于或低于用户最高分数。

表一: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
";

输出应如下所示:

你好 Lea,你的最高分:

pang 出战 x 2,最高分 60 分(最高分 70 分)....

pong 打了 x 1, 100 分,你有更高的分数....

【问题讨论】:

不完全是您想要的,但您可以有一个视图来存储所有游戏的列表以及每个游戏的前 2 名得分。在这种情况下,要么将最高分显示给用户,要么他们的分数是最高分,您可以将第二个分数显示为次佳。有了这个,你只需要 INNER JOIN 视图。 您使用的是哪个版本的 mysql 【参考方案1】:

在 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.

【讨论】:

绝对是的。 MySQL 的版本是 5.7,所以第二个查询就像一个魅力。子查询是必要的。非常感谢!!!

以上是关于查找具有特定标准的最大值并检查同一组是不是有更高/更低或任何值的主要内容,如果未能解决你的问题,请参考以下文章

每组最大 n,具有多个最大标准

检查firebase子项是不是具有特定值[重复]

TSQL查找组中的所有记录是不是具有相同的值

如何检查用户是不是具有特定角色并因此允许某些操作?

如何检查具有特定角色的成员是不是存在于 discord.js 的特定语音通道中

检查属性文件是不是存在并具有所需的属性