【问题标题】:Mysql Group By Levels rankingMysql Group By Levels 排名
【发布时间】:2019-01-18 00:02:29
【问题描述】:
rank    points  player_id   quiz_id
 1       88        1          40
 2       80        3          40
 3       30        3          41
 4       20        1          41

从以下查询获取此输出:

SELECT m.rank,
       m.scorer AS points,
       m.player_id
FROM
  ( SELECT d.player_id,
           d.scorer, @rownum := @rownum + 1 AS rank
   FROM
     ( SELECT t.player_id,
              SUM(t.score) AS scorer
      FROM answers t
      JOIN PROFILE ON profile.player_id = t.player_id
      JOIN quiz ON t.quiz_id = quiz.id
      WHERE t.is_active = 1
        AND quiz.contest_id = 1
        AND profile.signin_source_id != 1
        AND profile.is_active = 1
        AND t.quiz_id IN (1,
                          2)
      GROUP BY t.player_id
      ORDER BY scorer DESC, t.created_utc ASC) d,

     (SELECT @rownum := 0) r) m
WHERE m.scorer > 0

但是,我想要的输出是每个级别分离出来的排名。

rank    points  player_id   quiz_id
 1       88        1          40
 2       80        3          40
 1       30        3          41
 2       20        1          41

我关注了这些:

How to perform grouped ranking in MySQL

https://blog.sqlauthority.com/2014/03/09/mysql-reset-row-number-for-each-group-partition-by-row-number/

但无法获得所需的输出。任何建议或帮助表示赞赏。

【问题讨论】:

  • 你使用的是什么 MySQL 版本?
  • 5.7 是 MySQL 版本。

标签: mysql


【解决方案1】:

试试这个查询,IMO 更简单:

select @quiz_id_lag := 0, @rank := 1;

select rank, points, player_id, quiz_id from (
  select points,
         player_id,
         case when @quiz_id_lag = quiz_id then @rank := @rank + 1 else @rank := 1 end rank,
         @quiz_id_lag,
         @quiz_id_lag := quiz_id,
         quiz_id
  from tbl
  order by quiz_id, points desc
) a;

要将其合并到您的查询中,请尝试:

SELECT @quiz_id_lag := 0, @rank := 1;

SELECT rank,
       scorer AS points,
       player_id
FROM (
    SELECT quiz_id,
           player_id,
           scorer,
           CASE WHEN @quiz_id_lag = quiz_id THEN @rank := @rank + 1 ELSE @rank := 1 END rank,
           @quiz_id_lag := quiz_id,
           quiz_id
    FROM ( 
         SELECT t.player_id,
                SUM(t.score) AS scorer,
                t.quiz_id
         FROM answers t
         JOIN PROFILE ON profile.player_id = t.player_id
         JOIN quiz ON t.quiz_id = quiz.id
         WHERE t.is_active = 1 AND quiz.contest_id = 1 AND profile.signin_source_id != 1
           AND profile.is_active = 1 AND t.quiz_id IN (1, 2)
        GROUP BY t.player_id
    ) d
    WHERE scorer > 0
    ORDER BY quiz_id, scorer DESC
) m

【讨论】:

  • 您好,输出错误,只返回1级。
  • @KinshukLahiri 我认为您需要更改内部查询中的 WHERE 子句以获得所需的结果:WHERE t.is_active = 1 AND quiz.contest_id = 1 AND profile.signin_source_id != 1 AND profile.is_active = 1 AND t.quiz_id IN (1, 2)
【解决方案2】:

试试这个

SELECT m.rank,m.scorer AS points,m.player_id, m.quiz_id 
FROM (
    SELECT d.player_id,d.quiz_id, d.scorer,  
    @cur:= IF(quiz_id=@id, @cur+1, 1) AS rank, 
    @id := quiz_id 
    FROM (
            SELECT t.player_id, quiz.id as quiz_id, SUM(t.score) as scorer
            FROM answers t JOIN profile ON profile.player_id = t.player_id
                    JOIN quiz ON t.quiz_id = quize.id  
            WHERE t.is_active = 1 AND quiz.contest_id = 1
                    AND profile.signin_source_id != 1 AND profile.is_active = 1
                    AND t.quiz_id IN (1,2) 
            GROUP BY t.player_id, quiz.id 
            ORDER BY scorer DESC
    ) d, (SELECT @id:=(SELECT MIN(id) FROM quiz), @cur:=0) AS init
    order by d.quiz_id, d.scorer desc) m 
WHERE m.scorer > 0

【讨论】:

  • 感谢您的输入,但是我得到的排名是错误的。
  • 这是为 quiz_id 1 1008 55 529 1 返回的行但是,该特定玩家的排名是 893。
  • 这可能是“m.scorer > 0”的原因,所以如果负分不适用,则将该 m.scorer > 0 条件移动到最里面的 select 语句 where 子句为 t.score > 0
【解决方案3】:

终于得到了想要的结果,以查询结束,以便获得适当的级别排名:

SELECT m.rank,m.scorer AS points,m.player_id, m.quiz_id  FROM (
 SELECT d.player_id,d.scorer, 
    @rownum:= CASE WHEN @quiz_id <> d.quiz_id THEN 1 ELSE @rownum+1 END as rank, 
    @quiz_id:= d.quiz_id as quiz_id FROM 
    (SELECT @rownum := 1) r,
    (SELECT @quiz_id := 0) c,(
    SELECT t.player_id,SUM(t.score) as scorer, t.quiz_id 
    FROM answers t JOIN profile ON 
    profile.player_id = t.player_id
    JOIN quiz ON t.quiz_id = quiz.id
    WHERE t.is_active = 1 AND quiz.contest_id = 2 AND 
     profile.signin_source_id != 1 AND profile.is_active = 1
     GROUP BY t.player_id,t.quiz_id 
     ORDER BY quiz_id DESC,scorer DESC, t.created_utc ASC) d
   ) m 
WHERE m.scorer > 0 ORDER BY quiz_id

这将为特定组的所有级别提供整个结果集,如果想从特定组中获取特定级别的排名,请添加

AND t.quiz_id IN (1,2)  

感谢所有参与的人!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多