Reputation: 1607
How to order the rows with respect to multiple columns such that the ordering maintains the condition that if two people have the same details they get the same rank. I will give an example to illustrate :Here firstly ordering is done by score and in case of tie with penalty and still if tie exist both are given same rank and next person gets the adjusted rank.
###################
rank roll score penalty
1 11 3 23
2 12 3 20
2 13 3 20
2 14 3 20
5 15 2 10
So the question is how to fill the rank column??If not possible in mysql what is the other alternative??
Upvotes: 0
Views: 417
Reputation: 51868
Test data:
/*
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);
*/
And here it comes:
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;
You need to work with a temporary table here, because you can't update the table you are reading from. The temporary table will be automatically deleted when the session ends.
Upvotes: 1
Reputation: 171371
Try this:
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)
Upvotes: 0