テストデータ:
/*
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;
読み取り元のテーブルを更新できないため、ここで一時テーブルを操作する必要があります。セッションが終了すると、一時テーブルは自動的に削除されます。