query over number eliminacion creacion consultas con column adding actualizacion mysql indexing

over - row number column mysql



Con MySQL, ¿cómo puedo generar una columna que contenga el índice de registro en una tabla? (7)

¿Hay alguna forma de que pueda obtener el número de fila real de una consulta?

Quiero poder ordenar una tabla llamada league_girl por un campo llamado score; y devuelve el nombre de usuario y la posición de fila real de ese nombre de usuario.

Quiero clasificar a los usuarios para poder decir dónde está un usuario en particular, es decir. Joe está en la posición 100 de 200, es decir,

User Score Row Joe 100 1 Bob 50 2 Bill 10 3

He visto algunas soluciones aquí, pero he probado la mayoría de ellas y ninguna devuelve realmente el número de fila.

He intentado esto:

SELECT position, username, score FROM (SELECT @row := @row + 1 AS position, username, score FROM league_girl GROUP BY username ORDER BY score DESC)

Como derivado

... pero parece que no devuelve la posición de la fila.

¿Algunas ideas?


Aquí viene la estructura de la plantilla que utilicé:

select /*this is a row number counter*/ ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) as rownumber, d3.* from ( select d1.* from table_name d1 ) d3

Y aquí está mi código de trabajo:

select ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) as rownumber, d3.* from ( select year( d1.date ), month( d1.date ), count( d1.id ) from maindatabase d1 where ( ( d1.date >= ''2013-01-01'' ) and ( d1.date <= ''2014-12-31'' ) ) group by YEAR( d1.date ), MONTH( d1.date ) ) d3


Es posible que desee probar lo siguiente:

SELECT l.position, l.username, l.score, @curRow := @curRow + 1 AS row_number FROM league_girl l JOIN (SELECT @curRow := 0) r;

La parte JOIN (SELECT @curRow := 0) permite la inicialización de la variable sin requerir un comando SET separado.

Caso de prueba:

CREATE TABLE league_girl (position int, username varchar(10), score int); INSERT INTO league_girl VALUES (1, ''a'', 10); INSERT INTO league_girl VALUES (2, ''b'', 25); INSERT INTO league_girl VALUES (3, ''c'', 75); INSERT INTO league_girl VALUES (4, ''d'', 25); INSERT INTO league_girl VALUES (5, ''e'', 55); INSERT INTO league_girl VALUES (6, ''f'', 80); INSERT INTO league_girl VALUES (7, ''g'', 15);

Consulta de prueba:

SELECT l.position, l.username, l.score, @curRow := @curRow + 1 AS row_number FROM league_girl l JOIN (SELECT @curRow := 0) r WHERE l.score > 50;

Resultado:

+----------+----------+-------+------------+ | position | username | score | row_number | +----------+----------+-------+------------+ | 3 | c | 75 | 1 | | 5 | e | 55 | 2 | | 6 | f | 80 | 3 | +----------+----------+-------+------------+ 3 rows in set (0.00 sec)


Sé que el OP está pidiendo una respuesta de mysql pero como encontré que las otras respuestas no funcionan para mí,

  • La mayoría de ellos falla con el order by
  • O simplemente son muy poco eficientes y hacen que su consulta sea muy lenta para una tabla de grasa

Así que para ahorrar tiempo para otros como yo, simplemente indexe la fila después de recuperarlos de databse

ejemplo en PHP:

$users = UserRepository::loadAllUsersAndSortByScore(); foreach($users as $index=>&$user){ $user[''rank''] = $index+1; }

ejemplo en PHP usando desplazamiento y límite para paginación:

$limit = 20; //page size $offset = 3; //page number $users = UserRepository::loadAllUsersAndSortByScore(); foreach($users as $index=>&$user){ $user[''rank''] = $index+1+($limit*($offset-1)); }


Si solo quiere saber la posición de un usuario específico después del pedido por puntaje de campo, simplemente puede seleccionar todas las filas de su tabla donde el puntaje de campo es más alto que el puntaje actual del usuario. Y use el número de fila devuelto +1 para saber qué posición ocupa este usuario actual.

Suponiendo que su tabla es "league_girl" y su campo principal es "id", puede usar esto:

SELECT count(id) + 1 as rank from league_girl where score > <your_user_score>


Suponiendo que MySQL lo admite, puede hacer esto fácilmente con una subconsulta SQL estándar:

select (count(*) from league_girl l1 where l2.score > l1.score and l1.id <> l2.id) as position, username, score from league_girl l2 order by score;

Para grandes cantidades de resultados mostrados, esto será un poco lento y querrás cambiar a una auto unión en su lugar.


También puedes usar

SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...

para inicializar la variable de contador.


SELECT @i:=@i+1 AS iterator, t.* FROM tablename t,(SELECT @i:=0) foo