Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get next/previous record in MySQL?

Tags:

sql

mysql

People also ask

How can I get previous record in SQL?

SQL Server LAG() is a window function that provides access to a row at a specified physical offset which comes before the current row. In other words, by using the LAG() function, from the current row, you can access data of the previous row, or the row before the previous row, and so on.

How do I find the next row value in SQL?

For example, by using the LEAD() function, from the current row, you can access data of the next row, or the row after the next row, and so on. The LEAD() function can be very useful for comparing the value of the current row with the value of the following row.

How do I get last 3 records in SQL?

Try only this:- SELECT * FROM reset ORDER BY ASC LIMIT (FOUND_ROWS() - 3), 3 and check if it is giving the last 3 rows from your table in ascending order!!!

How do I add a previous row value in SQL?

You can now add an order by to the over( partition by and it will do a cumulative sum of the previous rows. I had used the over( partition by with a row_number before, but not to do a cumulative sum over previous rows.


next:

select * from foo where id = (select min(id) from foo where id > 4)

previous:

select * from foo where id = (select max(id) from foo where id < 4)

In addition to cemkalyoncu's solution:

next record:

SELECT * FROM foo WHERE id > 4 ORDER BY id LIMIT 1;

previous record:

SELECT * FROM foo WHERE id < 4 ORDER BY id DESC LIMIT 1;

edit: Since this answer has been getting a few upvotes lately, I really want to stress the comment I made earlier about understanding that a primary key colum is not meant as a column to sort by, because MySQL does not guarantee that higher, auto incremented, values are necessarily added at a later time.

If you don't care about this, and simply need the record with a higher (or lower) id then this will suffice. Just don't use this as a means to determine whether a record is actually added later (or earlier). In stead, consider using a datetime column to sort by, for instance.


All the above solutions require two database calls. The below sql code combine two sql statements into one.

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)
      )    

SELECT * FROM foo WHERE id>4 ORDER BY id LIMIT 1

I was attempting to do something similar to this, but I needed the results ordered by date since I can't rely on the ID field as a sortable column. Here's the solution I came up with.

First we find out the index of the desired record in the table, when it's sorted as we want:

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;

Then decrement the result by 2 put it in the limit statement. For example the above returned 21 for me so I run:

SELECT * 
FROM articles
ORDER BY date, id
LIMIT 19, 3

Gives you your primary record along with it's next and previous records given your stated order.

I tried to do it as a single database call, but couldn't get the LIMIT statement to take a variable as one of it's parameters.


Try this example.

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; 

Note: If value is not found then it will return null.

In the above example, Previous value will be Raja and Next value will be null because there is no next value.


Using @Dan 's approach, you can create JOINs. Just use a different @variable for each sub query.

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)