restar - ¿Cómo obtener el registro siguiente/anterior en MySQL?
siguiente registro php mysql (20)
Digamos que tengo registros con ID 3,4,7,9 y quiero poder ir de uno a otro navegando a través de los enlaces siguiente / anterior. El problema es que no sé cómo recuperar el registro con la ID más cercana.
Entonces, cuando tengo un registro con ID 4, necesito poder obtener el siguiente registro existente, que sería 7. La consulta probablemente se parecería a algo así como
SELECT * FROM foo WHERE id = 4 OFFSET 1
¿Cómo puedo buscar el registro siguiente / anterior sin obtener todo el conjunto de resultados y repetirlo manualmente?
Estoy usando MySQL 5.
¿Cómo obtener el registro siguiente / anterior en MySQL y PHP?
Mi ejemplo es obtener solo la identificación
function btn_prev(){
$id = $_POST[''ids''];
$re = mysql_query("SELECT * FROM table_name WHERE your_id < ''$id'' ORDER BY your_id DESC LIMIT 1");
if(mysql_num_rows($re) == 1)
{
$r = mysql_fetch_array($re);
$ids = $r[''your_id''];
if($ids == "" || $ids == 0)
{
echo 0;
}
else
{
echo $ids;
}
}
else
{
echo 0;
}
}
function btn_next(){
$id = $_POST[''ids''];
$re = mysql_query("SELECT * FROM table_name WHERE your_id > ''$id'' ORDER BY your_id ASC LIMIT 1");
if(mysql_num_rows($re) == 1)
{
$r = mysql_fetch_array($re);
$ids = $r[''your_id''];
if($ids == "" || $ids == 0)
{
echo 0;
}
else
{
echo $ids;
}
}
else
{
echo 0;
}
}
Además de cemkalyoncu''s solución cemkalyoncu''s :
próximo registro:
SELECT * FROM foo WHERE id > 4 ORDER BY id LIMIT 1;
récord anterior:
SELECT * FROM foo WHERE id < 4 ORDER BY id DESC LIMIT 1;
editar: Como esta respuesta ha recibido algunos votos favorables últimamente, realmente quiero enfatizar el comentario que hice antes sobre la comprensión de que una columna de clave primaria no se entiende como una columna para ordenar, porque MySQL no garantiza que sea más alta, aumente automáticamente. , los valores se agregan necesariamente en un momento posterior.
Si no te importa esto, y simplemente necesitas el registro con una id
más alta (o más baja), entonces esto será suficiente. Simplemente no use esto como un medio para determinar si un registro se agrega realmente más tarde (o antes). En lugar, considere usar una columna de fecha y hora para ordenar, por ejemplo.
Aquí tenemos una manera de buscar los registros anteriores y siguientes usando una sola consulta MySQL. Donde 5 es la identificación del registro actual.
select * from story where catagory=100 and (
id =(select max(id) from story where id < 5 and catagory=100 and order by created_at desc)
OR
id=(select min(id) from story where id > 5 and catagory=100 order by created_at desc) )
Creo que para tener la fila real siguiente o anterior en la tabla SQL necesitamos el valor real con igual, (<o>) devolver más de uno si necesita cambiar la posición de la fila en una tabla de pedidos.
Necesitamos la $position
valor para buscar en la fila de neighbours
En mi tabla, creé una columna ''posición''
y la consulta SQL para obtener la fila necesaria es:
para el siguiente:
SELECT *
FROM `my_table`
WHERE id = (SELECT (id)
FROM my_table
WHERE position = ($position+1))
LIMIT 1
para el anterior:
SELECT *
FROM my_table
WHERE id = (SELECT (id)
FROM my_table
WHERE `position` = ($position-1))
LIMIT 1
Esta es una solución universal para condiciones con más resultados similares.
<?php
$your_name1_finded="somethnig searched"; //$your_name1_finded must be finded in previous select
$result = db_query("SELECT your_name1 FROM your_table WHERE your_name=your_condition ORDER BY your_name1, your_name2"); //Get all our ids
$i=0;
while($row = db_fetch_assoc($result)) { //Loop through our rows
$i++;
$current_row[$i]=$row[''your_name1''];// field with results
if($row[''your_name1''] == $your_name1_finded) {//If we haven''t hit our current row yet
$yid=$i;
}
}
//buttons
if ($current_row[$yid-1]) $out_button.= "<a class=''button'' href=''/$your_url/".$current_row[$yid-1]."''>BUTTON_PREVIOUS</a>";
if ($current_row[$yid+1]) $out_button.= "<a class=''button'' href=''/$your_url/".$current_row[$yid+1]."''>BUTTON_NEXT</a>";
echo $out_button;//display buttons
?>
Hay otro truco que puede usar para mostrar columnas de filas anteriores, usando cualquier orden que desee, usando una variable similar al @row truco:
SELECT @prev_col_a, @prev_col_b, @prev_col_c,
@prev_col_a := col_a AS col_a,
@prev_col_b := col_b AS col_b,
@prev_col_c := col_c AS col_c
FROM table, (SELECT @prev_col_a := NULL, @prev_col_b := NULL, @prev_col_c := NULL) prv
ORDER BY whatever
Aparentemente, las columnas de selección se evalúan en orden, por lo que primero se seleccionarán las variables guardadas y luego se actualizarán las variables a la nueva fila (seleccionándolas en el proceso).
NB: No estoy seguro de que esto sea un comportamiento definido, pero lo he usado y funciona.
Intentaba hacer algo similar a esto, pero necesitaba los resultados ordenados por fecha, ya que no puedo confiar en el campo ID como columna ordenable. Aquí está la solución que se me ocurrió.
Primero descubrimos el índice del registro deseado en la tabla, cuando está ordenado como queremos:
SELECT row
FROM
(SELECT @rownum:=@rownum+1 row, a.*
FROM articles a, (SELECT @rownum:=0) r
ORDER BY date, id) as article_with_rows
WHERE id = 50;
Luego disminuya el resultado por 2 póngalo en la declaración de límite. Por ejemplo, lo anterior arrojó 21 para mí, así que corro:
SELECT *
FROM articles
ORDER BY date, id
LIMIT 19, 3
Le da su registro principal junto con sus registros siguientes y anteriores dada su orden establecida.
Traté de hacerlo como una sola llamada a la base de datos, pero no pude obtener la instrucción LIMIT para tomar una variable como uno de sus parámetros.
Mi solución para obtener el siguiente y las previsualizaciones también registran para volver al primer registro si estoy por el último y viceversa
No estoy usando la identificación. Estoy usando el título para la buena URL.
Estoy usando Codeigniter HMVC
$id = $this->_get_id_from_url($url);
//get the next id
$next_sql = $this->_custom_query("select * from projects where id = (select min(id) from projects where id > $id)");
foreach ($next_sql->result() as $row) {
$next_id = $row->url;
}
if (!empty($next_id)) {
$next_id = $next_id;
} else {
$first_id = $this->_custom_query("select * from projects where id = (SELECT MIN(id) FROM projects)");
foreach ($first_id->result() as $row) {
$next_id = $row->url;
}
}
//get the prev id
$prev_sql = $this->_custom_query("select * from projects where id = (select max(id) from projects where id < $id)");
foreach ($prev_sql->result() as $row) {
$prev_id = $row->url;
}
if (!empty($prev_id)) {
$prev_id = $prev_id;
} else {
$last_id = $this->_custom_query("select * from projects where id = (SELECT MAX(id) FROM projects)");
foreach ($last_id->result() as $row) {
$prev_id = $row->url;
}
}
Optimizar el enfoque @Don para usar solo una consulta
SELECT * from (
SELECT
@rownum:=@rownum+1 row,
CASE a.id WHEN ''CurrentArticleID'' THEN @currentrow:=@rownum ELSE NULL END as ''current_row'',
a.*
FROM articles a,
(SELECT @currentrow:=0) c,
(SELECT @rownum:=0) r
ORDER BY `date`, id DESC
) as article_with_row
where row > @currentrow - 2
limit 3
cambie CurrentArticleID con ID de artículo actual como
SELECT * from (
SELECT
@rownum:=@rownum+1 row,
CASE a.id WHEN ''100'' THEN @currentrow:=@rownum ELSE NULL END as ''current_row'',
a.*
FROM articles a,
(SELECT @currentrow:=0) c,
(SELECT @rownum:=0) r
ORDER BY `date`, id DESC
) as article_with_row
where row > @currentrow - 2
limit 3
Prueba este ejemplo.
create table student(id int, name varchar(30), age int);
insert into student values
(1 ,''Ranga'', 27),
(2 ,''Reddy'', 26),
(3 ,''Vasu'', 50),
(5 ,''Manoj'', 10),
(6 ,''Raja'', 52),
(7 ,''Vinod'', 27);
SELECT name,
(SELECT name FROM student s1
WHERE s1.id < s.id
ORDER BY id DESC LIMIT 1) as previous_name,
(SELECT name FROM student s2
WHERE s2.id > s.id
ORDER BY id ASC LIMIT 1) as next_name
FROM student s
WHERE id = 7;
Nota: Si no se encuentra el valor , devolverá nulo .
En el ejemplo anterior, el valor anterior será Raja y el valor Siguiente será nulo porque no hay próximo valor.
Seleccione arriba 1 * de foo donde id> 4 ordene por id asc
Si desea next_id
más de un id
a su consulta y obtener next_id
para todos ellos ...
Asigne cur_id
en su campo de selección y luego aliméntelo para subconsultar y obtenga next_id
dentro del campo de selección. Y luego selecciona solo next_id
.
Usando la respuesta de Longneck para calc next_id
:
select next_id
from (
select id as cur_id, (select min(id) from `foo` where id>cur_id) as next_id
from `foo`
) as tmp
where next_id is not null;
Si tiene una columna de índice, dig id, puede devolver la identificación anterior y la siguiente en una solicitud sql. Reemplazar: id con tu valor
SELECT
IFNULL((SELECT id FROM table WHERE id < :id ORDER BY id DESC LIMIT 1),0) as previous,
IFNULL((SELECT id FROM table WHERE id > :id ORDER BY id ASC LIMIT 1),0) as next
Siguiente fila
SELECT * FROM `foo` LIMIT number++ , 1
Fila anterior
SELECT * FROM `foo` LIMIT number-- , 1
muestra de la siguiente fila
SELECT * FROM `foo` LIMIT 1 , 1
SELECT * FROM `foo` LIMIT 2 , 1
SELECT * FROM `foo` LIMIT 3 , 1
muestra fila anterior
SELECT * FROM `foo` LIMIT -1 , 1
SELECT * FROM `foo` LIMIT -2 , 1
SELECT * FROM `foo` LIMIT -3 , 1
SELECT * FROM `foo` LIMIT 3 , 1
SELECT * FROM `foo` LIMIT 2 , 1
SELECT * FROM `foo` LIMIT 1 , 1
Todas las soluciones anteriores requieren dos llamadas a la base de datos. El siguiente código sql combina dos sentencias SQL en una.
select * from foo
where (
id = IFNULL((select min(id) from foo where id > 4),0)
or id = IFNULL((select max(id) from foo where id < 4),0)
)
Tuve el mismo problema que Dan, así que utilicé su respuesta y la mejoré.
Primero seleccione el índice de fila, nada diferente aquí.
SELECT row
FROM
(SELECT @rownum:=@rownum+1 row, a.*
FROM articles a, (SELECT @rownum:=0) r
ORDER BY date, id) as article_with_rows
WHERE id = 50;
Ahora usa dos consultas separadas. Por ejemplo, si el índice de fila es 21, la consulta para seleccionar el siguiente registro será:
SELECT *
FROM articles
ORDER BY date, id
LIMIT 21, 1
Para seleccionar el registro anterior use esta consulta:
SELECT *
FROM articles
ORDER BY date, id
LIMIT 19, 1
Tenga en cuenta que para la primera fila (el índice de fila es 1), el límite irá a -1 y obtendrá un error de MySQL. Puede usar un enunciado if para evitar esto. Simplemente no seleccione nada, ya que no hay ningún registro previo de todos modos. En el caso del último registro, habrá una fila siguiente y, por lo tanto, no habrá resultado.
También tenga en cuenta que si utiliza DESC para ordenar, en lugar de ASC, sus consultas para seleccionar las filas siguiente y anterior siguen siendo las mismas, pero cambiadas.
Usando el enfoque de @Dan, puedes crear JOINs. Simplemente use una @variable diferente para cada consulta secundaria.
SELECT current_row.row, current_row.id, previous_row.row, previous_row.id
FROM (
SELECT @rownum:=@rownum+1 row, a.*
FROM articles a, (SELECT @rownum:=0) r
ORDER BY date, id
) as current_row
LEFT JOIN (
SELECT @rownum2:=@rownum2+1 row, a.*
FROM articles a, (SELECT @rownum2:=0) r
ORDER BY date, id
) as previous_row ON
(current_row.id = previous_row.id) AND (current_row.row = previous_row.row - 1)
siguiente:
select * from foo where id = (select min(id) from foo where id > 4)
anterior:
select * from foo where id = (select max(id) from foo where id < 4)
CREATE PROCEDURE `pobierz_posty`(IN iduser bigint(20), IN size int, IN page int)
BEGIN
DECLARE start_element int DEFAULT 0;
SET start_element:= size * page;
SELECT DISTINCT * FROM post WHERE id_users ....
ORDER BY data_postu DESC LIMIT size OFFSET start_element
END
SELECT * FROM foo WHERE id>4 ORDER BY id LIMIT 1