[sql] MySQL에서 다음 / 이전 기록을 얻는 방법?

ID가 3,4,7,9 인 레코드가 있고 다음 / 이전 링크를 통해 탐색하여 서로간에 이동할 수 있기를 원한다고 가정합니다. 문제는 가장 높은 ID로 레코드를 가져 오는 방법을 모른다는 것입니다.

따라서 ID 4의 레코드가있는 경우 기존 레코드 인 7을 가져올 수 있어야합니다. 쿼리는 다음과 같습니다.

SELECT * FROM foo WHERE id = 4 OFFSET 1

전체 결과 세트를 가져 오지 않고 수동으로 반복하지 않고 다음 / 이전 레코드를 가져 오는 방법은 무엇입니까?

MySQL 5를 사용하고 있습니다.



답변

다음:

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

이전:

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


답변

셈 칼리 온쿠 외에도 솔루션 :

다음 기록 :

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

이전 기록 :

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

편집 : 이 답변은 최근에 몇 가지 upvotes를 받고 있기 때문에, 나는 내가 한 의견 을 강조하고 싶습니다 으므로 MySQL은 기본 키 열이 정렬 할 열로 의미가 없다는 것을 이해하기 위해 앞서 .MySQL은 더 높은 자동 증가를 보장하지 않기 때문입니다. 값은 나중에 추가해야합니다.

이것에 신경 쓰지 않고 단순히 더 높은 (또는 더 낮은) 레코드가 필요하다면 id이것으로 충분합니다. 레코드가 실제로 나중에 추가되는지 또는 이전에 추가되는지 여부를 판별하기위한 수단으로 이것을 사용하지 마십시오. 대신 날짜 시간 열을 사용하여 정렬하는 것을 고려하십시오.


답변

위의 모든 솔루션에는 두 개의 데이터베이스 호출이 필요합니다. 아래의 SQL 코드는 두 개의 SQL 문을 하나로 결합합니다.

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


답변

이와 비슷한 작업을 시도했지만 ID 필드를 정렬 가능한 열로 사용할 수 없으므로 날짜별로 정렬 된 결과가 필요했습니다. 내가 생각해 낸 해결책은 다음과 같습니다.

먼저 원하는 정렬 순서대로 테이블에서 원하는 레코드의 인덱스를 찾습니다.

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;

그런 다음 결과를 2 씩 줄이면 limit 문에 넣습니다. 예를 들어 위의 내용은 21을 반환하므로 다음을 실행합니다.

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

명시된 순서대로 다음 레코드 및 이전 레코드와 함께 기본 레코드를 제공합니다.

단일 데이터베이스 호출로 시도했지만 매개 변수 중 하나로 변수를 사용하는 LIMIT 문을 가져올 수 없습니다.


답변

이 예제를 시도하십시오.

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; 

참고 : 경우 값이 발견되지 후 반환됩니다 널 (null)을 .

위의 예에서
이전 값은 Raja 이고 다음 값 은 없으므로 다음 값은 null 입니다.


답변

@Dan의 접근 방식을 사용하여 JOIN을 만들 수 있습니다. 각 하위 쿼리마다 다른 @ 변수를 사용하십시오.

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)