My assumption is that you first compute the ranking of each character, and then use it in the case argument in the update.
The following query shows one way to calculate the ranking:
select t.*, @rn := if(@marks = marks, @rn, @rn + 1) as ranking, @marks := marks from myTable t cross join (select @rn := 0, @marks := -1) const order by t.marks desc;
(As a note: Iām a little uncomfortable with this method because MySQL does not guarantee the order of evaluation of two expressions with constants. If @marks were set before @rn , this will not work In practice, this does not seem to happen. And it is more efficient, than the equivalent with a correlated subquery.)
Then you can put this in update with join :
update myTable join (select t.*, @rn := if(@marks = marks, @rn, @rn + 1) as ranking, @marks := marks from myTable t cross join (select @rn := 0, @marks := -1) const order by t.marks desc ) mr on myTable.Name = mr.Name set myTable.Points := (case when mr.ranking = 1 then 3 when mr.ranking = 2 then 2 when mr.ranking = 3 then 1 else 0 end);
This has been tested on your SQL script.
Gordon linoff
source share