MySQL在小组赛男子奖牌中的排名

MySQL在小组赛男子奖牌中的排名,mysql,greatest-n-per-group,partition,row-number,Mysql,Greatest N Per Group,Partition,Row Number,我们的足球队每场比赛都有“最佳球员”投票结果。 现在我想要前三名或前四、五名,以金、银、铜为背景,票数相等。 我更喜欢使用SQL查询而不是php代码来定义代码 我的网站查询现在返回以下内容: Game - Player - Points Arsenal - Bart - 25 Arsenal - Joris - 17 Arsenal - Tim - 16 Arsenal - Tom - 16 Arsenal - Victor - 7 Arsenal - Jo - 1 Chelsea - Tim

我们的足球队每场比赛都有“最佳球员”投票结果。 现在我想要前三名或前四、五名,以金、银、铜为背景,票数相等。 我更喜欢使用SQL查询而不是php代码来定义代码

我的网站查询现在返回以下内容:

Game - Player - Points
Arsenal - Bart - 25
Arsenal - Joris - 17
Arsenal - Tim - 16
Arsenal - Tom - 16
Arsenal - Victor - 7
Arsenal - Jo - 1
Chelsea - Tim - 15
Chelsea - Bart - 15
Chelsea - Tom - 13
Chelsea - Ken - 10
Chelsea - Victor - 7
Chelsea  - Edris - 1
我很难得到这个结果:

Game - Player - Points - Rank
Arsenal - Bart - 25 - 1
Arsenal - Joris - 17 - 2
Arsenal - Tim - 16 - 3 
Arsenal - Tom - 16 - 3
Arsenal - Victor - 7 - 4
Arsenal - Jo - 1 - 5
Chelsea - Tim - 15 - 1 
Chelsea - Bart - 15 - 1
Chelsea - Tom - 13 - 2
Chelsea - Ken - 10 - 3
Chelsea - Victor - 7 - 4
Chelsea  - Edris - 1 - 5
更好的是,这将是完美的,但我想更难

Game - Player - Points - Rank
Arsenal - Bart - 25 - 1
Arsenal - Joris - 17 - 2
Arsenal - Tim - 16 - 3 
Arsenal - Tom - 16 - 3
Arsenal - Victor - 7 - 5
Arsenal - Jo - 1 - 6
Chelsea - Tim - 15 - 1
Chelsea - Bart - 15 - 1
Chelsea - Tom - 13 - 3
Chelsea - Ken - 10 - 4
Chelsea - Victor - 7 - 5
Chelsea  - Edris - 1 - 6
有什么建议吗?
这只是tbl_MOTM Id、游戏、玩家、积分

也许使用用户变量的小技巧会有所帮助

首先,需要定义要排序的数据集。假设您已经有了这样一个表:

Game | Player | Points
因此,您的查询应该类似于:

select game, player, points
from your_table
-- Where conditions go here
order by points desc
现在,让我们使用一个变量来完成您需要的操作:

select a.game, a.player
     , @rank := @rank + (case when a.points != @points then 1 else 0 end) as rank
     , @points := a.points as points
from (select @rank := 0, @points := 0) as init
   , your_table as a
-- Where conditions go here
order by a.points desc
如果要筛选此项以获得排名5或以上且只有5行或更少行的所有玩家:

select b.*
from (
    select a.game, a.player
         , @rank := @rank + (case when a.points != @points then 1 else 0 end) as rank
         , @points := a.points as points
    from (select @rank := 0, @points := 0) as init
       , your_table as a
    -- Where conditions go here
    order by a.points desc
) as b
where rank <= 5
order by rank
limit 5
如果需要按特定顺序排列列,请将上述查询包含在子查询中,或创建一个临时表。我更喜欢这样:

drop table if exists temp_result;
create temporary table temp_result
select a.player
     , @rank := (case 
                    when a.game != @game then 1
                    when a.points != @points then @rank
                    else @rank + 1
                end) as rank
     , @game := a.game as game
     , @points := a.points as points
from
    (select @game := ''
          , @points := 0
          , @rank := 0
    ) as init,
    your_table as a
-- Where conditions go here
order by a.game, a.points desc;
alter table temp_result
    add index idx_player(player),
    add index idx_game(game),
    add index idx_rank(rank);
-- Select top-5 players for each game:
select game, player, points, rank
from temp_result
where rank <= 5
order by game, rank;
请记住:临时表仅对创建临时表的连接可见,一旦创建临时表的连接关闭或终止,临时表将被删除。

@Barranka:

非常感谢,我几乎可以复制粘贴您的代码,需要在此处进行小编辑:

select a.player
     , @rank := (case 
                    when a.game != @game then 1
                    when a.points = @points then @rank -- EDITED != to =
                    else @rank + 1
                end) as rank
     , @game := a.game as game
     , @points := a.points as points
from
    (select @game := ''
          , @points := 0
          , @rank := 0
    ) as init,
    your_table as a
-- Where conditions go here
order by a.game, a.points desc

这将给出我在第一个问题中预期的结果,当有3人获得nr1分数时,排名不会从1跃升到4。但这是我自己可以做的事,只要付出一点额外的努力。非常感谢

这在MySQL中不像在其他dbms中那么容易,因为缺少分析函数。你为什么需要这个?你不使用编程语言来显示结果吗?Java,PHP,什么?然后使用此选项为第一列着色。在我看来,不需要排名号。这是一个每组前n名的问题,在mysql中不容易做到。我习惯于使用Microsoft MSSQL和视图/存储过程。我需要排名,这样我就可以创建一个tbl_RankColorCode来定义php网站中记录的背景。但在Mysql中,这似乎相当困难,所以我想我确实需要编写php循环来定义RankColor。但我将首先尝试下面的解决方案。谢谢,谢谢,我来测试一下。例如,你说从你的_表中选择游戏,玩家,点数,按点数说明顺序,但这应该是按游戏顺序,点数说明。这样做会更难吗?@Joris不一定。。。这只是一个在案例中定义重置条件的问题…以care@Joris检查我的编辑。。。我想这回答了你的问题
select a.player
     , @rank := (case 
                    when a.game != @game then 1
                    when a.points = @points then @rank -- EDITED != to =
                    else @rank + 1
                end) as rank
     , @game := a.game as game
     , @points := a.points as points
from
    (select @game := ''
          , @points := 0
          , @rank := 0
    ) as init,
    your_table as a
-- Where conditions go here
order by a.game, a.points desc