php mysql pagination seek

php - Buscar un registro específico en los resultados paginados de MySQL



pagination seek (5)

Podría usar una sub consulta para crear una tabla con los resultados y su posición, y luego consultarla para la entrada específica que está viendo:

SET @rank=0; SELECT rank, record FROM ( SELECT @rank:=@rank+1 AS rank, record FROM table ) as subquery WHERE record = x;

La tabla devuelta mostraría el registro y el rango que apareció en la consulta original. Puede dividir el rango por el número de resultados por página ... O compilarlo en la consulta. Espero que esto ayude.

Tengo un sistema de paginación clásico que usa LIMIT startrecord, endrecord y quiero averiguar en qué número de página se encuentra un registro X.

La única idea que tengo ahora es buscar recursivamente todos los registros para descubrirlo. ¡Pero estoy buscando un método mucho más "económico"!

Algunas ideas ?


Indique la cantidad de registros anteriores al que está buscando. Esto requiere que usted asuma un pedido para su consulta que es natural.

SELECT COUNT(id) AS c FROM tbl WHERE sort_field < ((SELECT sort_field FROM tbl WHERE id = 18)) OR (sort_field = ((SELECT sort_field FROM tbl WHERE id = 18)) AND id < 18);

Luego solo recupera la c y calcula el ceilling(c/page_size) . Esto le dará el número de página en el que caerá su registro. Lo único importante que debe recordar es que debe ordenar los registros en el mismo orden que lo haría en su consulta con límite.

Para describir lo que hace la consulta, cuenta los registros numéricos que se encuentran delante del registro con id 18. La única parte difícil es con registros con el mismo valor que para su sort_field de sort_field en el cual MySQL hará uso de la clave principal y en nuestro caso id . Y es por eso que tenemos la parte OR en nuestra condición. En mi respuesta, supongo que está ordenando su consulta original (con la instrucción de límite) ascendente, pero si ordena de forma descendente, debe cambiar todo < to > .


Realmente no se puede crear una forma "económica". Debe obtener la lista completa de registros del DB ya que no hay forma de conocer la posición de un registro de MySQL.

Dependiendo de su clasificación, la frecuencia a la cual los datos cambian, puede asignarle al registro su posición en una columna: agregue la posición de la columna a la tabla que está consultando. Eso podría no ser factible en todos los casos.


Use algo como esto con su consulta como parte de la subselección s

SELECT s.row, s.RECORD, YOUR_OTHER_FIELDS... FROM (SELECT @row := 0) cnt JOIN (SELECT @row := @row + 1 row, RECORD, ...YOUR QUERY WITH ORDER BY ...) s WHERE s.RECORD = <desired record number>

y divide la fila por el tamaño de página de tu paginación. Ejemplo concreto pero sin sentido:

SELECT p.row, p.id FROM (SELECT @row := 0) cnt JOIN (SELECT @row := @row + 1 row, id FROM products ORDER BY id desc) p WHERE p.id = 485166

Según lo previsto, el valor de la row cambia con el orden que usa en la subselección.

Dobla la inicialización variable en la consulta, por lo que esta es solo una declaración. Tampoco depende de un orden natural o distribución de filas, siempre y cuando el orden en que se devuelvan permanezca igual para cualquier ORDEN que especifique (o omita).


si esto es algo que utilizará a menudo, creo que es una buena idea crear un procedimiento almacenado o una función . Podemos usar un cursor en el interior para recorrer los resultados y obtener la posición del elemento deseado. Creo que esto será más rápido, no tendrá que iterar a todos los registros, y no necesita una subconsulta (por todo esto diría que es más económico) y puede usar el orden, unirse y todo lo que necesite.

DELIMITER $$ CREATE FUNCTION position ( looking_for INT ) RETURNS INT READS SQL DATA BEGIN -- First we declare all the variables we will need DECLARE id INT; DECLARE pos INT; SET pos=0; -- flag which will be set to true, when cursor reaches end of table DECLARE exit_loop BOOLEAN; -- Declare the sql for the cursor DECLARE pos_cursor CURSOR FOR SELECT id FROM your_table --you can use where, join, group by, order and whatever you need --end of query -- Let mysql set exit_loop to true, if there are no more rows to iterate DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE; -- open the cursor OPEN example_cursor; -- marks the beginning of the loop example_loop: LOOP -- read the id from next row into the variable id FETCH pos_cursor INTO id; -- increment the pos var SET pos=pos+1; -- check if we found the desired item, -- if it has been set we close the cursor and exit -- the loop IF id=looking_for THEN CLOSE example_cursor; LEAVE example_loop; END IF; -- check if the exit_loop flag has been set by mysql, -- if it has been set we close the cursor and exit -- the loop IF exit_loop THEN CLOSE example_cursor; LEAVE example_loop; END IF; END LOOP example_loop; RETURN pos; END $$ DELIMITER ;

Usted crea la función solo una vez, y para usarla, solo necesita usar este sql:

CALL position(ID_OF_THE_ITEM_YOU_ARE_LOOKING_FOR);

y devuelve la posición del artículo, en la posición [0] [0] del conjunto de filas devuelto.

Por supuesto, en lugar de la identificación, puede crear una función que compare el nombre, o cualquier otro campo, o incluso más de uno.

Si la consulta es siempre diferente , no puede usar una función, pero puede usar el cursor (la sintaxis será la misma). Puedes construir el cursor en tu PHP, dejar que sea una variable del Sistema (usando @pos), y en cualquier caso simplemente agregar el sql específico de la consulta (la parte entre DECLARE pos_cursor CURSOR FOR y --end of query )