在对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
尽管Al和Amy的成绩相同,但其中一个等级高于另一个。艾米被扯掉了。我怎样才能让艾米和艾尔拥有相同的排名,这样他们的排名都是1.另外,威廉和玛丽没有参加考试。他们上课并在男孩的房间里吸烟。他们应该并列最后一个位置。
正确的排名应该是:
Students Rank Grades
========================
Al 1 90
Amy 1 90
George 2 78
Bob 3 73
Mary 4 NULL
William 4 NULL
如果有人有任何建议,请告诉我。
答案 0 :(得分: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。
答案 1 :(得分:1)
听起来像是一个中间件规则,可以在数据库和客户端之间的代码中更好地表达。
如果那是不可能的,我建议MySQL中的存储过程在您编写时运行查询,然后使用游标和数组修改结果。