选择每组列中的最大值

Selecting highest value in column per group

我正在为一款 moba 游戏制作数据库,我正在尝试进行查询,以 return 每场比赛中获胜率最高的英雄(假设没有平局)。每个Game有两支队伍,每支队伍有五个selected_hero对应一个英雄。我想要的是 Game_Id、Hero.Hero_Name 和 Hero.Win_Rate。到目前为止,我能够获得该游戏中的 Game_Id 和最高胜率,但每当我尝试添加 Hero.Hero_Name 时,它会 return 包含每场游戏中的每个英雄他们的胜率。

表格设置如下:

CREATE TABLE Game(
    Game_Id INT NOT NULL PRIMARY KEY
);

CREATE TABLE Team (
    Team_Id INT NOT NULL PRIMARY KEY
    Game_Id INT NOT NULL, 
    FOREIGN KEY(Game_Id) REFERENCES Game(Game_Id)
);

CREATE TABLE Hero (
    Hero_Id INT NOT NULL PRIMARY KEY,
    Hero_Name VARCHAR(30),
    Win_Rate DECIMAL(5,4)
);

CREATE TABLE Selected_Hero (
    Hero_Id INT NOT NULL,
    Team_Id INT NOT NULL
    FOREIGN KEY(Hero_Id) REFERENCES Hero(Hero_Id),
    FOREIGN KEY(Team_Id) REFERENCES Team(Team_Id)
);

这是给我每场比赛 game_id 和最大值 win_rate 但没有英雄名称的查询:

SELECT Game.Game_Id, MAX(Hero.Win_Rate)
FROM Game
JOIN Team ON Game.Game_Id = Team.Game_Id 
JOIN Selected_Hero ON Team.Team_Id = Selected_Hero.Team_Id
JOIN Hero ON Selected_Hero.Hero_Id = Hero.Hero_Id
GROUP BY Game.Game_Id;

如果我使用以下内容,每个英雄及其在每场比赛中的胜率都是 returned,但它是按 game_id 和 win_rate 排序的,所以如果我可以每个 game_id 组的第一行,它会给我我想要的:

SELECT * FROM (
SELECT DISTINCT Game.Game_Id, Hero.Hero_Name AS heroName, MAX(Hero.Win_Rate) AS winRate
FROM Game
JOIN Team ON Game.Game_Id= Team.Game_Id
JOIN Selected_Hero ON Team.Team_Id = Selected_Hero.Team_Id
JOIN Hero ON Selected_Hero.Hero_Id = Hero.Hero_Id
GROUP BY Game.Game_Id, Hero.Hero_Name
ORDER BY Game_Id, winRate DESC
);

使用RANK:

WITH cte AS (
    SELECT Game.Game_Id,
           RANK() OVER (PARTITION BY Game.Game_Id
                        ORDER BY Hero.Win_Rate DESC) rnk
    FROM Game
    INNER JOIN Team ON Game.Game_Id = Team.Game_Id 
    INNER JOIN Selected_Hero ON Team.Team_Id = Selected_Hero.Team_Id
    INNER JOIN Hero ON Selected_Hero.Hero_Id = Hero.Hero_Id
)

SELECT *
FROM cte
WHERE rnk <= 2;  -- for 1st and 2nd; for 2nd only use rnk = 2

如果没有关系,您可以使用 FIRST 聚合函数。

SELECT
  Game.Game_Id,
  Team.Team_id,
  max(Hero.Hero_Name) keep(dense_rank first
    ORDER BY Hero.Win_Rate DESC
  ) as hero_name
FROM Game
    INNER JOIN Team
      ON Game.Game_Id = Team.Game_Id 
    INNER JOIN Selected_Hero
      ON Team.Team_Id = Selected_Hero.Team_Id
    INNER JOIN Hero
      ON Selected_Hero.Hero_Id = Hero.Hero_Id
GROUP BY Game.Game_id, Team.Team_Id

但是如果你需要为第一个英雄添加很多其他的附加列,最好使用RANK而不是重复这个长添加。