如何对多个级别的表进行排序

时间:2015-02-20 07:46:51

标签: mysql rank

我遇到了一个基于单个结果表创建和排序排行榜的问题。以下是我尝试做的一个简单示例;

table results;
 Name RaceNo Time
 Sam   1     34 
 Ben   1     27
 Sam   2     29
 Ken   1     30
 Ben   2     32
 Sam   3     35
 Ken   2     33
 Ken   3     38
 Ben   3     33

RaceNo =最多16个左右;  姓名=最多50个左右;

我想按如下方式获得排序输出;  输出有一系列种族,按总计

排序
 Name R1 R2 R3 Total(sum R1-n)
 Ben  27 32 33   92
 Sam  34 29 35   98
 Ken  30 33 38  101

我真正想要的是;  期望的输出是每个种族排名为1-n,而总和(排名)的排序按总和(排名)排序。

 Name Rnk1 Rnk2 Rnk3 Total(sum Rank1-n)
 Ben   1    2    1    4
 Sam   3    1    2    6
 Ken   2    3    3    8

我不知道如何处理这个问题。以下将对单一种族进行排名,但我不知道如何将所有种族串联成一个查询。

select Name, find_in_set( Time, (select group_concat(Time order by Time) from 
results where RaceNo=1)) as rank from results where RaceNo=1;

距离我想做的事情还有很长的路要走。我考虑在PHP中循环,但我确信在MySQL中有更好的方法。 如果有人能提供帮助,我会非常感激吗?

2 个答案:

答案 0 :(得分:1)

你已经完成了最大的工作:

通过这种方式,您可以在平面列中获得所有等级

  SELECT RaceNo, Name,
       FIND_IN_SET( Time,
              (SELECT GROUP_CONCAT(Time order by Time)
                   FROM results WHERE RaceNo=m1.RaceNo)) as rank 
  FROM results m1;

你必须更进一步才能获得特定的比赛:

  SELECT m2.Name, SUM(IF(m2.RaceNo=1, m2.rank, 0)) R1
  FROM (SELECT RaceNo, Name, FIND_IN_SET( Time,
                (SELECT GROUP_CONCAT(Time order by Time)
                 FROM results 
                 WHERE RaceNo=m1.RaceNo)) as rank
        FROM results m1) m2 GROUP BY m2.Name;

因此,您可以为执行以下操作的所有种族生成查询

  ## generating the different columns
  SELECT CONCAT(GROUP_CONCAT(
            CONCAT("SUM(IF(m2.RaceNo=", RaceNo, ", m2.rank, 0)) R", RaceNo)),
            ", SUM(m2.rank) Total")
    INTO @query
    FROM (SELECT DISTINCT RaceNo FROM results ) m;

  ## inserting the columns in our previous request
  SELECT CONCAT("SELECT m2.Name, ", @query,
               " FROM (SELECT RaceNo, Name, FIND_IN_SET( Time,
                           (SELECT GROUP_CONCAT(Time order by Time)
                            FROM results WHERE RaceNo=m1.RaceNo)) as rank
                       FROM results m1) m2 GROUP BY m2.Name;")
    INTO @query;

  ## execute it as a statement
  mysql> PREPARE stmt FROM @query;
  mysql> EXECUTE stmt;
  +------+------+------+------+-------+
  | Name | R1   | R2   | R3   | Total |
  +------+------+------+------+-------+
  | Ben  |    1 |    2 |    1 |     4 |
  | Ken  |    2 |    3 |    3 |     8 |
  | Sam  |    3 |    1 |    2 |     6 |
  +------+------+------+------+-------+
  3 rows in set (0.00 sec)

答案 1 :(得分:0)

第一个结果,

SELECT Name,
       MAX(CASE WHEN RaceNo=1 THEN Time END) AS R1,
       MAX(CASE WHEN RaceNo=2 THEN Time END) AS R2,
       MAX(CASE WHEN RaceNo=3 THEN Time END) AS R3,
       IFNULL(MAX(CASE WHEN RaceNo=1 THEN Time END),0)+
       IFNULL(MAX(CASE WHEN RaceNo=2 THEN Time END),0)+
       IFNULL(MAX(CASE WHEN RaceNo=3 THEN Time END),0) AS Total
FROM TableName
GROUP BY Name

结果:

NAME    R1  R2  R3  TOTAL
Ben     27  32  33  92
Ken     30  33  38  101
Sam     34  29  35  98

请参阅SQL Fiddle中的结果。