查询每场比赛的最佳得分手
Query to get the best scorer per game
我需要计算每个 game_id
的最佳得分手 (player_id
/ player_name
)。正如您在下面看到的,我有三种情况:
- 两个或更多人的进球数相同:在这种情况下,我们没有得分手。
- 一个人是唯一的进球者。
- 我们有一位得分手显然得分最高。
我试图查询每场比赛的最佳得分手 game_id
、player_name
、player_id
,但没有成功。这是我的查询:
select j.id as game_id,jg.id as player_id, jg.nome s player_name,
count(g.id) as numberOfGoals,
RANK() OVER(PARTITION BY j.id ORDER BY count(g.id) ) as rank
from jogo j
inner join jogo_jogador jj on jj.jogo_id = j.id
inner join golo g on g.jogo_jogador_id = jj.id
inner join equipa_jogador ej on ej.id = jj.equipa_jogador_id
inner join jogador jg on jg.id = ej.jogador_id
group by jg.id, jg.nome, j.id
order by j.id, jg.nome, jg.id;
这是我目前得到的:
insert into tbl(game_id player_id player_name numberofgoals rank)
values
(1 , 1 ,'Marco Costa' ,1 ,1),
(1 , 4 ,'Olivier Marques',1 ,1),
(2 , 1 ,'Marco Costa' ,1 ,1),
(3 , 9 ,'Ilidio Vatuva' ,2 ,2),
(3 ,10 ,'Joaquim Barros' ,1 ,1),
(4 ,11 ,'Diogo Mendonça' ,2 ,4),
(4 ,10 ,'Joaquim Barros' ,1 ,1),
(4 ,14 ,'John Smith' ,1 ,1),
(4 ,12 ,'Mário Jorge' ,1 ,1),
(5 , 7 ,'Ricardo Pereira',1 ,1),
(6 , 8 ,'Danilo Barbosa' ,1 ,1),
(6 , 9 ,'Ilidio Vatuva' ,1 ,1),
(6 ,19 ,'Micael Pereira' ,1 ,1),
(6 ,18 ,'Ricardo Bateiro',2 ,4),
(7 , 8 ,'Danilo Barbosa' ,3 ,1),
(9 , 8 ,'Danilo Barbosa' ,1 ,1),
(9 , 2 ,'Joao Azevedo' ,1 ,1),
(9 , 7 ,'Ricardo Pereira',1 ,1),
(10, 9 ,'Ilidio Vatuva' ,1 ,1),
(11, 3 ,'Kevin Soares' ,1 ,1),
(11, 1 ,'Marco Costa' ,1 ,1),
(11,18 ,'Ricardo Bateiro',2 ,3),
(12,21 ,'Daniel Silva' ,1 ,1),
(12, 9 ,'Ilidio Vatuva' ,1 ,1),
(13, 2 ,'Joao Azevedo' ,1 ,1);
我正在使用 PostgreSQL 13.2。
对于game_id 1(例如):
- 如果我 运行 没有限制的子查询,我会得到两个可能的赢家,目标数相同 (1)。在那种情况下,我们没有得分手。我们不选择任何人。
- 如果我运行带有Limit的子查询,它会选择一个玩家。
the best scorer(player_id/player_name) per game_id.
走出去,这可能会做到:
SELECT j.id AS game_id
, x.player_id
, jg.nome AS player_name
, x.number_of_goals
FROM jogo j
JOIN LATERAL (
SELECT jj.id AS player_id
, count(*) AS number_of_goals
, lag(count(*)) OVER (ORDER BY count(*) DESC) AS next_best -- descending!
FROM jogo_jogador jj
JOIN golo g ON g.jogo_jogador_id = jj.id
WHERE jj.jogo_id = j.id
GROUP BY jj.id
ORDER BY count(*) DESC, next_best DESC NULLS LAST
LIMIT 1
) x ON x.number_of_goals > x.next_best -- better than the next best
OR x.next_best IS NULL -- or there was no next best
JOIN jogador jg ON jg.id = x.player_id;
在 LATERAL
子查询 x
中,我计算每个球员的进球数,按降序排列球员(DESC
!),然后选择得分最高的球员 - 如果比下一个最好的(或者没有下一个最好的)。
next_best
是使用 window 函数 lag()
确定的,基于相同的降序。
关于DESC NULLS LAST
:
- Sort NULL values to the end of a table
之后只检索实际获胜者的玩家姓名。
在不知道你的关系设计的情况下,我假设 jogo_jogador.id
实际上是玩家 ID (jogador.id
),根本不需要加入 equipa_jogador
。
使用稍快的 count(*)
(而不是 count(g.id)
),因为我们可以。
我需要计算每个 game_id
的最佳得分手 (player_id
/ player_name
)。正如您在下面看到的,我有三种情况:
- 两个或更多人的进球数相同:在这种情况下,我们没有得分手。
- 一个人是唯一的进球者。
- 我们有一位得分手显然得分最高。
我试图查询每场比赛的最佳得分手 game_id
、player_name
、player_id
,但没有成功。这是我的查询:
select j.id as game_id,jg.id as player_id, jg.nome s player_name,
count(g.id) as numberOfGoals,
RANK() OVER(PARTITION BY j.id ORDER BY count(g.id) ) as rank
from jogo j
inner join jogo_jogador jj on jj.jogo_id = j.id
inner join golo g on g.jogo_jogador_id = jj.id
inner join equipa_jogador ej on ej.id = jj.equipa_jogador_id
inner join jogador jg on jg.id = ej.jogador_id
group by jg.id, jg.nome, j.id
order by j.id, jg.nome, jg.id;
这是我目前得到的:
insert into tbl(game_id player_id player_name numberofgoals rank)
values
(1 , 1 ,'Marco Costa' ,1 ,1),
(1 , 4 ,'Olivier Marques',1 ,1),
(2 , 1 ,'Marco Costa' ,1 ,1),
(3 , 9 ,'Ilidio Vatuva' ,2 ,2),
(3 ,10 ,'Joaquim Barros' ,1 ,1),
(4 ,11 ,'Diogo Mendonça' ,2 ,4),
(4 ,10 ,'Joaquim Barros' ,1 ,1),
(4 ,14 ,'John Smith' ,1 ,1),
(4 ,12 ,'Mário Jorge' ,1 ,1),
(5 , 7 ,'Ricardo Pereira',1 ,1),
(6 , 8 ,'Danilo Barbosa' ,1 ,1),
(6 , 9 ,'Ilidio Vatuva' ,1 ,1),
(6 ,19 ,'Micael Pereira' ,1 ,1),
(6 ,18 ,'Ricardo Bateiro',2 ,4),
(7 , 8 ,'Danilo Barbosa' ,3 ,1),
(9 , 8 ,'Danilo Barbosa' ,1 ,1),
(9 , 2 ,'Joao Azevedo' ,1 ,1),
(9 , 7 ,'Ricardo Pereira',1 ,1),
(10, 9 ,'Ilidio Vatuva' ,1 ,1),
(11, 3 ,'Kevin Soares' ,1 ,1),
(11, 1 ,'Marco Costa' ,1 ,1),
(11,18 ,'Ricardo Bateiro',2 ,3),
(12,21 ,'Daniel Silva' ,1 ,1),
(12, 9 ,'Ilidio Vatuva' ,1 ,1),
(13, 2 ,'Joao Azevedo' ,1 ,1);
我正在使用 PostgreSQL 13.2。
对于game_id 1(例如):
- 如果我 运行 没有限制的子查询,我会得到两个可能的赢家,目标数相同 (1)。在那种情况下,我们没有得分手。我们不选择任何人。
- 如果我运行带有Limit的子查询,它会选择一个玩家。
the best scorer(player_id/player_name) per game_id.
走出去,这可能会做到:
SELECT j.id AS game_id
, x.player_id
, jg.nome AS player_name
, x.number_of_goals
FROM jogo j
JOIN LATERAL (
SELECT jj.id AS player_id
, count(*) AS number_of_goals
, lag(count(*)) OVER (ORDER BY count(*) DESC) AS next_best -- descending!
FROM jogo_jogador jj
JOIN golo g ON g.jogo_jogador_id = jj.id
WHERE jj.jogo_id = j.id
GROUP BY jj.id
ORDER BY count(*) DESC, next_best DESC NULLS LAST
LIMIT 1
) x ON x.number_of_goals > x.next_best -- better than the next best
OR x.next_best IS NULL -- or there was no next best
JOIN jogador jg ON jg.id = x.player_id;
在 LATERAL
子查询 x
中,我计算每个球员的进球数,按降序排列球员(DESC
!),然后选择得分最高的球员 - 如果比下一个最好的(或者没有下一个最好的)。
next_best
是使用 window 函数 lag()
确定的,基于相同的降序。
关于DESC NULLS LAST
:
- Sort NULL values to the end of a table
之后只检索实际获胜者的玩家姓名。
在不知道你的关系设计的情况下,我假设 jogo_jogador.id
实际上是玩家 ID (jogador.id
),根本不需要加入 equipa_jogador
。
使用稍快的 count(*)
(而不是 count(g.id)
),因为我们可以。