mysql总和每位玩家前5名得分并列入排名

时间:2017-05-04 08:47:24

标签: mysql sql

我希望排名最后5位得分的球员排名并进行排名。玩家有大约5分。

现在我有以下查询:

set @count:=0, @player:=''; 
SELECT SEIZOEN
     , WEDSTRIJDTYPE
     , ATLEET_ID
     , GROEP_NAAM
     , GROEP_OMS
     , SUM(PUNTEN_WC) as WC_RESULT 
  FROM 
     ( SELECT ATLEET_ID
            , PUNTEN_WC
            , SEIZOEN
            , WEDSTRIJDTYPE
            , GROEP_NAAM
            , GROEP_OMS     
         FROM 
            ( SELECT PUNTEN_WC
                   , SEIZOEN
                   , WEDSTRIJDTYPE
                   , GROEP_NAAM
                   , GROEP_OMS
                   , @count := if (@player != ATLEET_ID,0,@count + 1) as count
                   , @player := ATLEET_ID as ATLEET_ID  
                FROM 
                   ( SELECT ATLEET_ID
                          , PUNTEN_WC
                          , k.SEIZOEN
                          , k.WEDSTRIJDTYPE
                          , g.GROEP_NAAM
                          , g.GROEP_OMS 
                       FROM RESULTATEN r 
                       LEFT 
                       JOIN KALENDER k 
                         ON r.KALENDER_ID = k.KALENDER_ID
                       JOIN GROEP_SNB g 
                         ON r.GROEP_NAAM = g.GROEP_NAAM
                       JOIN SKIER s 
                         ON r.ATLEET_ID = s.SKIER_ID
                      WHERE k.WEDSTRIJDTYPE = 'Dutch Cup snowboard '  
                        AND k.SEIZOEN = '2016-2017'    
                      order 
                         by ATLEET_ID
                          , PUNTEN_WC DESC          
                   ) x
            ) y   
        where count < 6
     ) z  
 GROUP 
    BY ATLEET_ID 
 ORDER 
    BY GROEP_NAAM
     , WC_RESULT DESC 
 LIMIT 0,2000;

问题是这个查询并没有取得每个玩家的五个最佳分数。

当我运行最内在的查询时,它会对分数进行排序。

SELECT ATLEET_ID
     , PUNTEN_WC
     , k.SEIZOEN
     , k.WEDSTRIJDTYPE
     , g.GROEP_NAAM
     , g.GROEP_OMS 
  FROM RESULTATEN r 
  LEFT 
  JOIN KALENDER k 
    ON r.KALENDER_ID = k.KALENDER_ID 
  JOIN GROEP_SNB g 
    ON r.GROEP_NAAM = g.GROEP_NAAM
  JOIN SKIER s 
    ON r.ATLEET_ID = s.SKIER_ID
 WHERE k.WEDSTRIJDTYPE = 'Dutch Cup snowboard '  
   AND k.SEIZOEN = '2016-2017'    
 order 
    by ATLEET_ID
     , PUNTEN_WC DESC

我已经对记录进行了计数,因此我可以将其限制在5的最佳状态。但是麻烦就开始了。使用第二个查询时,仍然可以正确排序高分,但是count-field不是0到5?

因此,当我将第三个查询放入其中时,当count-field为5时停止,但我希望每个玩家最多获得5个分数。

1 个答案:

答案 0 :(得分:1)

您可以使用此查询对每个人的前N个值求和:

创建一个简单的测试表并填充它 -

CREATE TABLE Scores
    (`id` int, `playerName` varchar(16), `score` int)
;

INSERT INTO Scores
    (`id`, `playerName`, `score`)
VALUES
    (1, 'Joe', 5),
    (2, 'Joe', 5),
    (3, 'Joe', 5),
    (4, 'Joe', 1),
    (5, 'Joe', 10),
    (6, 'Joe', 10),
    (7, 'Joe', 15),
    (8, 'Bob', 5),
    (9, 'Bob', 5),
    (10, 'Bob', 2),
    (11, 'Bob', 10),
    (12, 'Bob', 3),
    (13, 'Bob', 10),
    (14, 'Bob', 20)
;

查询:

SET @score_rank := 0;
SET @current_player  = '';
SET @topN = 5;
Select playerName, SUM(score)
From (Select playerName, score,
        @score_rank := IF(@current_player = playerName, (@score_rank + 1), 1) AS score_rank,
        @current_player := playerName
      From Scores 
      Order By playerName, score DESC) sorted
Where score_rank <= @topN
Group By playerName;

内部查询将值分配给两个变量 - @current_player@score_rank。如果@current_player值与playerName匹配,则会增加@score_rank,否则会将@score_rank设置为1.通过这样做,我们只能抓住每个玩家的前5名。外部查询然后将前5个分数相加。如果您想要总结另一组(如前10名),则可以更改@topN的值。

以上样本表的结果:

playerName  SUM(score)
----------  ----------
Bob         50
Joe         45

请在此处查看:http://rextester.com/CLO11640