7

在 mysql 查询中对结果进行排名时如何处理关系?我在这个例子中简化了表名和列,但它应该能说明我的问题:

SET @rank=0;

   SELECT student_names.students, 
          @rank := @rank +1 AS rank, 
          scores.grades
     FROM student_names  
LEFT JOIN scores ON student_names.students = scores.students
 ORDER BY scores.grades DESC

所以想象上面的查询产生:

Students  Rank  Grades
=======================
Al         1     90
Amy        2     90
George     3     78
Bob        4     73
Mary       5     NULL
William    6     NULL

尽管艾尔和艾米的成绩相同,但其中一个的排名高于另一个。艾米被骗了。我怎样才能使 Amy 和 Al 具有相同的排名,使他们都有 1 的排名。另外,William 和 Mary 没有参加测试。他们打包上课,在男孩的房间里抽烟。他们应该并列最后一名。

正确的排名应该是:

Students  Rank  Grades
========================
Al         1     90
Amy        1     90
George     2     78
Bob        3     73
Mary       4     NULL
William    4     NULL

如果有人有任何建议,请告诉我。

4

2 回答 2

16

编辑:这是 MySQL 4.1+ 支持

采用:

   SELECT st.name,
          sc.grades,
          CASE 
            WHEN @grade = COALESCE(sc.grades, 0) THEN @rownum 
            ELSE @rownum := @rownum + 1 
          END AS rank,
          @grade := COALESCE(sc.grades, 0)
     FROM STUDENTS st
LEFT JOIN SCORES sc ON sc.student_id = st.id
     JOIN (SELECT @rownum := 0, @grade := NULL) r
 ORDER BY sc.grades DESC

您可以使用交叉连接(在 MySQL 中,没有任何条件的 INNER JOIN)来声明和使用变量,而无需使用单独的SET语句。

您需要 COALESCE 来正确处理 NULL。

于 2010-03-19T01:30:35.273 回答
1

听起来像是一个中间件规则,可以更好地用位于数据库和客户端之间的代码来表达。

如果这不可能,我建议在 MySQL 中使用存储过程来运行查询,然后使用游标和数组修改结果。

于 2010-03-19T01:07:19.473 回答