选择每组列中的最大值
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
而不是重复这个长添加。
我正在为一款 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
而不是重复这个长添加。