解决 mySQL 中每个组的最大得分球员

Posted

技术标签:

【中文标题】解决 mySQL 中每个组的最大得分球员【英文标题】:Solving max Scoring player from each group in mySQL 【发布时间】:2020-12-08 18:43:39 【问题描述】:

请参阅另一个 Stack Overflow 问题 here,但那里的答案不包括 group_id 3 播放器。 我试图在 mysql 中复制答案,但我不熟悉 PostgreSQL。任何人都可以展示如何在 MySQL 中进行操作?

问题是从每个组返回最高得分球员winner_id

create table players (
      player_id integer not null unique,
      group_id integer not null
  );

  create table matches (
      match_id integer not null unique,
      first_player integer not null,
      second_player integer not null,
      first_score integer not null,
      second_score integer not null
  );

insert into players values(20, 2);
insert into players values(30, 1);
insert into players values(40, 3);
insert into players values(45, 1);
insert into players values(50, 2);
insert into players values(65, 1);
insert into matches values(1, 30, 45, 10, 12);
insert into matches values(2, 20, 50, 5, 5);
insert into matches values(13, 65, 45, 10, 10);
insert into matches values(5, 30, 65, 3, 15);
insert into matches values(42, 45, 65, 8, 4);

matches

match_id | first_player | second_player | first_score | second_score
  ----------+--------------+---------------+-------------+--------------
   1        | 30           | 45            | 10          | 12
   2        | 20           | 50            | 5           | 5
   13       | 65           | 45            | 10          | 10
   5        | 30           | 65            | 3           | 15
   42       | 45           | 65            | 8           | 4

预期输出

group_id | winner_id
  ----------+-----------
   1        | 45
   2        | 20
   3        | 40

【问题讨论】:

您的问题应该有一个问题,而不是链接。 Partition by 在 MySQL 版本 8 之前不受支持。所以要么升级,要么使用这样的解决方法; ***.com/a/20432371/8194026 【参考方案1】:

我认为,由于您无法使用 MySQL 5.7 或更低版本的其他问题的解决方案。在这种情况下,您必须模拟ROW_NUMBER/PARTITION 功能,您可以使用来自每个玩家得分的派生表中的LEFT JOIN 来完成它,加入score 大于第一个表中的值。任何在连接表中得分没有更高的玩家显然得分最高。由于可能存在平局,因此我们从该表中取 player_id 值中的最小值(当没有平局时,这无效)。

SELECT group_id, MIN(player_id) AS player_id
FROM (
  SELECT t1.group_id, t1.player_id
  FROM (
    SELECT p.player_id, p.group_id,
           SUM(CASE WHEN m.first_player = p.player_id THEN m.first_score
               ELSE m.second_score
               END) AS score
    FROM players p
    LEFT JOIN matches m ON m.first_player = p.player_id OR m.second_player = p.player_id
    GROUP BY p.player_id, p.group_id
  ) t1
  LEFT JOIN (
    SELECT p.player_id, p.group_id,
           SUM(CASE WHEN m.first_player = p.player_id THEN m.first_score
               ELSE m.second_score
               END) AS score
    FROM players p
    LEFT JOIN matches m ON m.first_player = p.player_id OR m.second_player = p.player_id
    GROUP BY p.player_id, p.group_id
  ) t2 ON t2.group_id = t1.group_id AND t2.score > t1.score
  GROUP BY t1.group_id, t1.player_id
  HAVING COUNT(t2.player_id) = 0
) w
GROUP BY group_id

输出:

group_id    player_id
1           45
2           20
3           40

Demo on db-fiddle

【讨论】:

@NordicFox 这回答了你的问题吗?如果没有,您能否提供更多信息来帮助回答?

以上是关于解决 mySQL 中每个组的最大得分球员的主要内容,如果未能解决你的问题,请参考以下文章

找到每个球员最长的连续得分

用多态性保持球员在多项运动中得分

MySQL按顺序查找每组最近/最大的记录

格式化二维数组中输入的数据

返回每个组的最大值,但是当存在平局时,在 MySQL 中返回一个具有较低 id 的值

蟒蛇统计分析