sql >> Base de Datos >  >> RDS >> Mysql

Rango de actualización de MySQL simple con vínculos

Aquí hay una solución alternativa:¡no almacene rangos en absoluto! :-)

Puedes calcularlos sobre la marcha.

Ejemplo:

SELECT id, (@next_rank := IF(@score <> score, 1, 0)) nr, 
           (@score := score) score, (@r := IF(@next_rank = 1, @r + 1, @r)) rank 
FROM rank, (SELECT @r := 0) dummy1
ORDER BY score DESC;

Resultado:

  +------+----+-------+------+
  | id   | nr | score | rank |
  +------+----+-------+------+
  |    2 |  1 |    23 |    1 |
  |    4 |  1 |    17 |    2 |
  |    1 |  0 |    17 |    2 |
  |    5 |  1 |    10 |    3 |
  |    3 |  1 |     2 |    4 |
  +------+----+-------+------+

nr aquí hay una columna auxiliar que indica si debemos asignar el siguiente rango o no.

Puede envolver esta consulta en otro select y realizar paginación, por ejemplo.

SELECT id, score, rank 
FROM (SELECT id, (@next_rank := IF(@score <> score, 1, 0)) nr, 
           (@score := score) score, (@r := IF(@next_rank = 1, @r + 1, @r)) rank
      FROM rank, (SELECT @r := 0) dummy1
      ORDER BY score DESC) t
      WHERE rank > 1 and rank < 3;

Resultado:

  +------+-------+------+
  | id   | score | rank |
  +------+-------+------+
  |    4 |    17 |    2 |
  |    1 |    17 |    2 |
  +------+-------+------+

PRECAUCIÓN :desde ahora rank es una columna calculada, no puede indexarla y paginar de manera eficiente en el conjunto de datos (es decir, "seleccionar registros con rangos de 3000 a 3010"). Pero sigue siendo bueno para "seleccionar los primeros N rangos" (siempre que coloque un LIMIT correspondiente en una consulta)