Clasificar usuarios en mysql por sus puntos

Estoy tratando de clasificar a mis estudiantes por sus puntos que he calculado antes, pero el problema es que si los estudiantes tienen los mismos puntos, ambos deberían estar en el mismo range.

El estudiante 1 tiene puntos completos El estudiante 2 tiene puntos completos

ambos deben ser clasificados como 1;

enter image description here Aquí un ejemplo de mi database

la consulta que estoy tratando de hacer es (solo para seleccionar, entonces puedo insert los valores en mi columna)

SELECT a.points count(b.points)+1 as rank FROM examresults a left join examresults b on a.points>b.points group by a.points; 

Editar por ser más claro:

  • Estudiante 1 puntos 80
  • Estudiante 2 puntos 77.5
  • Estudiante 3 puntos 77.5
  • Estudiante 4 puntos 77

sus ranges deberían ser como

  • Estudiante 1 Rango 1
  • Estudiante 2 Rango 2
  • Estudiante 3 Rango 2
  • Estudiante 4 Rango 3

mi consulta actual devuelve valores como

enter image description here

Como falta el tercer range. (porque el segundo range tiene 2 valores)

Esta es solo una solución de la solución de Gordon que usa variables. La cuestión es que la function de range no es la forma en que el range debería funcionar. (el estudiante 4 debe ser el range 4)

Demostración de SQL Fiddle Puede agregar más estudiantes para mejorar las testings.

 select er.*, (@rank := if(@points = points, @rank, if(@points := points, @rank + 1, @rank + 1 ) ) ) as ranking from students er cross join (select @rank := 0, @points := -1) params order by points desc; 

SALIDA

 | id | points | ranking | |----|--------|---------| | 1 | 80 | 1 | | 2 | 78 | 2 | | 3 | 78 | 2 | | 4 | 77 | 3 | | 5 | 66 | 4 | | 6 | 66 | 4 | | 7 | 66 | 4 | | 8 | 15 | 5 | 

Desea un range real, que se calcula mediante la function de rank() estándar ANSI rank() . Puede implementar esto en MySQL usando esta lógica:

 select er.*, (select 1 + count(*) from examresults er2 where er2.points > er.points ) as ranking from exampleresults er; 

Para tablas más grandes, puede hacer esto con variables, pero es bastante incómodo:

 select er.*, (@rank := if(@rn := @rn + 1 -- increment row number if(@points = points, @rank, -- do not increment rank if(@points := points, -- set @points @rn, @rn -- otherwise use row number ) ) ) ) as ranking from examresults er cross join (select @rn := 0, @rank := 0, @points := -1) params order by points desc; 

esta consulta logra lo que quieres:

 SELECT student_id , points, (select count(distinct(points))+1 as rank from examresults internal where internal.points > external.points order by points) FROM examresults external group by student_id