如何在mysql中针对多个列排序行

时间:2012-06-29 14:14:08

标签: mysql sql-order-by

如何针对多个列对行进行排序,以便排序保持条件:如果两个人具有相同的详细信息,则他们获得相同的排名。我将举一个例子来说明:这里首先通过分数进行排序,如果与罚款相关,仍然如果存在并且两者都被赋予相同的排名而下一个人获得调整后的排名。

###################
rank roll score penalty
 1    11    3     23
 2    12    3     20
 2    13    3     20
 2    14    3     20
 5    15    2     10

那么问题是如何填充排名列?如果不可能在mysql中有什么是另一种选择?

2 个答案:

答案 0 :(得分:1)

测试数据:

/*
drop table test;
create table test (roll int, score int, penalty int);
insert into test (roll, score, penalty) values (11, 3, 23), (12, 3, 20), (13, 3, 20), (14,3,20), (15, 2, 10);
*/

它来了:

ALTER TABLE test ADD COLUMN `rank` int FIRST;
CREATE TEMPORARY TABLE tmp_test LIKE test;
INSERT INTO tmp_test (`rank`, roll, score, penalty)
SELECT cast(q.`rank` as unsigned integer) as `rank`, roll, score, penalty FROM (
SELECT IF(@prev != CONCAT(sq.score, '_', sq.penalty), @rownum:=@rownum2, @rownum) AS rank, 
@prev:=CONCAT(sq.score, '_', sq.penalty), 
@rownum2:=@rownum2 + 1,
sq.*
FROM (
  SELECT
  roll, score, penalty
  FROM
  test
  , (SELECT @rownum:=0, @prev:='', @rownum2:=1) r 
  ORDER BY score DESC, penalty DESC
) sq
) q;

UPDATE test t INNER JOIN tmp_test tt ON t.roll = tt.roll AND t.score = tt.score AND t.penalty = tt.penalty
SET t.rank = tt.rank;
/*optionally...*/    
DROP TABLE tmp_test;

您需要在此处使用临时表,因为您无法更新正在阅读的表。会话结束后,临时表将自动删除。

答案 1 :(得分:0)

试试这个:

SET @row = 0; 
select min(a.Row) as Rank, s.Roll, s.Score, s.Penalty
from (
    select @row := @row + 1 AS Row, 
        Roll, 
        Score, 
        Penalty
    from Score
    order by Score desc, Penalty desc
) a
inner join Score s on a.Score = s.Score and a.Penalty = s.Penalty
group by Roll, Score, Penalty
order by min(Row)