查询每场比赛的最佳得分手

Query to get the best scorer per game

我需要计算每个 game_id 的最佳得分手 (player_id / player_name)。正如您在下面看到的,我有三种情况:

我试图查询每场比赛的最佳得分手 game_idplayer_nameplayer_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(例如):

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)),因为我们可以。