복붙노트

[SQL] 어떻게 MySQL의에서 다음 / 이전 기록을 얻으려면?

SQL

어떻게 MySQL의에서 다음 / 이전 기록을 얻으려면?

내가 ID를 3,4,7,9로 기록이 내가 이전 / 다음 링크를 통해 탐색하여 다른 하나에서 갈 수하고 싶은 말은. 문제는 내가 가까운 높은 ID와 기록을 인출하는 방법을 알고하지 않는 것이있다.

내가 ID 4 기록이 때, 나는 7. 쿼리 아마 같이 보일 것이다 것 다음 기존 레코드를 가져올 수 있어야합니다

SELECT * FROM foo WHERE id = 4 OFFSET 1

어떻게 전체 결과 세트를 가져 오는 수동으로 반복하지 않고 다음 / 이전 기록을 가져올 수 있습니까?

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

해결법

  1. ==============================

    1.다음:

    다음:

    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)
    
  2. ==============================

    2.cemkalyoncu의 솔루션에 추가 :

    cemkalyoncu의 솔루션에 추가 :

    다음 레코드 :

    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을 보장하지 않기 때문에 높은, 자동 증가하는 것이, 나는 기본 키 콜 럼이 정렬에 열으로 의미되지 않는다는 것을 이해에 대해 이전에 만든 주석을 강조 할 , 값은 반드시 나중에 추가됩니다.

    당신이 걱정하고 단순히 더 높은 (또는 낮은) ID로 기록이 필요하지 않으면 다음이 충분합니다. 그냥 기록이 실제로 (또는 이전) 나중에 추가 여부를 확인하는 수단으로 이것을 사용하지 마십시오. 대신에, 예를 들어 기준으로 정렬 날짜 시간 열을 사용하는 것이 좋습니다.

  3. ==============================

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

    위의 모든 솔루션은 두 개의 데이터베이스 호출을 필요로한다. 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)
          )    
    
  4. ==============================

    4.

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

    5.나는이와 비슷한 뭔가를 시도했습니다,하지만 난 정렬 열로 ID 필드에 의존 할 수 없기 때문에 나는 결과를 날짜별로 정렬이 필요했다. 여기에 내가 생각 해낸 해결책이다.

    나는이와 비슷한 뭔가를 시도했습니다,하지만 난 정렬 열로 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) 제한 문에 넣어하여 다음 결과를 감소. 내가 실행할 수 있도록 예를 들어, 위에서 나를 위해 (21)을 반환

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

    당신에게 그것의 다음 및 이전 기록이 당신이 순서 주어진과 함께 기본 기록을 제공합니다.

    나는 하나의 데이터베이스 호출로하려고 노력하지만, 그것의 매개 변수 중 하나로 변수를 적용하려면 LIMIT 문을 가져올 수 없습니다.

  6. ==============================

    6.이 예제를보십시오.

    이 예제를보십시오.

    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을 반환합니다.

    상기 예에서, 이전 값은 다음 값이 없기 때문에 라자하고 다음 값이 null이됩니다 될 것입니다.

  7. ==============================

    7.@Dan의 접근 방식을 사용하여 조인을 만들 수 있습니다. 그냥 각각의 서브 쿼리에 대해 다른 @variable를 사용합니다.

    @Dan의 접근 방식을 사용하여 조인을 만들 수 있습니다. 그냥 각각의 서브 쿼리에 대해 다른 @variable를 사용합니다.

    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)
    
  8. ==============================

    8.다음 행

    다음 행

    SELECT * FROM `foo` LIMIT number++ , 1
    

    이전 행

    SELECT * FROM `foo` LIMIT number-- , 1
    

    샘플 다음 행

    SELECT * FROM `foo` LIMIT 1 , 1
    SELECT * FROM `foo` LIMIT 2 , 1
    SELECT * FROM `foo` LIMIT 3 , 1
    

    샘플 이전 행

    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
    
  9. ==============================

    9.그래서 나는 그의 대답을 사용하고 개선, 댄과 같은 문제가 있었다.

    그래서 나는 그의 대답을 사용하고 개선, 댄과 같은 문제가 있었다.

    먼저 여기에 행 인덱스, 아무것도 다른를 선택합니다.

    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;
    

    이제 두 개의 쿼리를 사용합니다. 행 지수가 21 인 경우 예를 들어, 다음 레코드를 선택하는 쿼리가 될 것입니다 :

    SELECT * 
    FROM articles
    ORDER BY date, id
    LIMIT 21, 1
    

    이전 기록의 사용이 쿼리를 선택합니다 :

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

    첫 번째 행 (행 인덱스가 1)에 대한 한계가 갈 것입니다 -1 당신은 MySQL의 오류가 발생합니다 있음을 유의하십시오. 이를 방지하기 위해 IF-문을 사용할 수 있습니다. 더 이전 기록 어쨌든이 없기 때문에 그냥 아무것도 선택하지 마십시오. 마지막 레코드의 경우, 다음 행이있을 것 및 그 어떤 결과가 없을 것입니다.

    또한 당신이 주문을 위해 DESC를 사용하는 경우, 대신 ASC, 당신이 다음 및 이전 행이 여전히 동일하지만 전환 선택 쿼리 것을 명심하십시오.

  10. ==============================

    10.이 개 같은 결과 조건에 대한 보편적 인 솔루션입니다.

    이 개 같은 결과 조건에 대한 보편적 인 솔루션입니다.

    <?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
    ?>
    
  11. ==============================

    11.여기에서 우리는 하나의 MySQL의 쿼리를 사용하여 이전 및 다음 레코드를 가져올 수있는 방법이있다. 어디 5는 현재 레코드의 id이다.

    여기에서 우리는 하나의 MySQL의 쿼리를 사용하여 이전 및 다음 레코드를 가져올 수있는 방법이있다. 어디 5는 현재 레코드의 id이다.

    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) )
    
  12. ==============================

    12.어떻게 MySQL은 & PHP에서 다음 / 이전 기록을 얻으려면?

    어떻게 MySQL은 & PHP에서 다음 / 이전 기록을 얻으려면?

    내 예는 ID 만 얻을 수 있습니다

    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;
      }
    }
    
  13. ==============================

    13.단 하나의 쿼리를 사용하는 @Don 접근 방식을 최적화

    단 하나의 쿼리를 사용하는 @Don 접근 방식을 최적화

    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
    

    변화와 같은 현재의 기술 자료 CurrentArticleID

    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
    
  14. ==============================

    14.당신이 원하는 순서를 사용하여 @row 트릭과 같은 변수를 사용하여, 이전 행의 열을 표시하는 데 사용할 수있는 또 다른 트릭이있다 :

    당신이 원하는 순서를 사용하여 @row 트릭과 같은 변수를 사용하여, 이전 행의 열을 표시하는 데 사용할 수있는 또 다른 트릭이있다 :

    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
    

    이 첫 번째 (그 과정에서 그들을 선택) 새 행에 변수를 갱신 한 후 저장된 변수를 선택하고 않도록 분명히, 선택 열, 순서대로 평가됩니다.

    NB : 나는하지 않도록이 동작을 정의되어 있는지,하지만 난 그것을 사용했습니다 그것은 작동합니다.

  15. ==============================

    15.당신은 그들 모두를위한 쿼리 및 Get next_id에 하나 개 이상의 ID를 공급하려면 ...

    당신은 그들 모두를위한 쿼리 및 Get next_id에 하나 개 이상의 ID를 공급하려면 ...

    지정은 선택 필드에 cur_id 다음 next_id 내부 선택 필드를 받고 하위 쿼리에 공급. 그리고 단지 next_id 선택합니다.

    CALC next_id에 longneck 응답을 사용하여 :

    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;
    
  16. ==============================

    16.

    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
    
  17. ==============================

    17.당신은 인덱스 컬럼이있는 경우, 당신은 하나 개의 SQL 요청에서 이전 및 다음 ID를 반환 할 수 있습니다 말한다. 교체 : ID를 당신의 가치

    당신은 인덱스 컬럼이있는 경우, 당신은 하나 개의 SQL 요청에서 이전 및 다음 ID를 반환 할 수 있습니다 말한다. 교체 : ID를 당신의 가치

    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
    
  18. ==============================

    18.내 솔루션은 다음 및 이전 기록을 얻을 수 있습니다 내가 마지막으로 그 반대가있어 경우에도 첫 번째 레코드로 다시 얻을 수 있습니다

    내 솔루션은 다음 및 이전 기록을 얻을 수 있습니다 내가 마지막으로 그 반대가있어 경우에도 첫 번째 레코드로 다시 얻을 수 있습니다

    나는 내가 좋은하는 URL의 제목을 사용하고 ID를 사용하지 않는

    나는 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;
        }     
    }
    
  19. ==============================

    19.여기에 내 대답이다. 나는 '점잖은 물장난'에서 아이디어를 선택하고 ID가 분 (ID) 및 최대 (ID) 사이 인 경우 체크 된 부분을 추가합니다. 여기 내 테이블을 생성하는 부분이다.

    여기에 내 대답이다. 나는 '점잖은 물장난'에서 아이디어를 선택하고 ID가 분 (ID) 및 최대 (ID) 사이 인 경우 체크 된 부분을 추가합니다. 여기 내 테이블을 생성하는 부분이다.

    CREATE TABLE Users (
    UserID int NOT NULL auto_increment,
    UserName varchar(45),
    UserNameID varchar(45),
    PRIMARY KEY (UserID)
    

    );

    다음 단계는 이전의 ID를 얻기위한 책임이 저장 프로 시저를 만드는 것입니다.

        CREATE DEFINER=`root`@`localhost` PROCEDURE `printPreviousIDbySelectedIDUser`(
    IN ID int,
    IN search_name varchar(45)
    )
    BEGIN
    SELECT CONCAT(ns.UserID) AS 'Previous ID' from Users ns
     where ns.UserName=search_name AND ns.UserID IN (select min(ns.UserID) from Users ns where ns.UserID > ID 
     union select max(ns.UserID) from Users ns where  ns.UserID < ID) LIMIT 1 ;
    END
    

    그렇지 않은 경우 첫 번째 방법은 인덱스가 정렬되면 좋지만. 당신은 인덱스가있는 경우 예를 들어, : 1,2,7과 다른 접근 방법을 사용하는 것이 훨씬 더 이런 식으로 인덱스 번호 (2)를 얻을 필요가있다.

        CREATE DEFINER=`root`@`localhost` PROCEDURE `getPreviousUserID`(
    IN ID int,
    IN search_name varchar(45)
    )
    BEGIN
    SELECT CONCAT(ns.UserID) AS 'Previous ID' from Users ns
      WHERE ns.UserName=search_name AND  ns.UserID < ID   ORDER BY ns.UserID DESC LIMIT 1;
    END
    
  20. ==============================

    20.100 % 작업

    100 % 작업

    SELECT * FROM `table` where table_id < 3 ORDER BY `table_id` DESC limit 1
    
  21. ==============================

    21.나는 우리가 더는 주문 표에 행의 위치가 변경해야하는 경우보다 동일한 (<또는>) 반환과 실제 값을 필요 SQL 테이블에서 실제 다음 또는 이전 행을 가지고 생각합니다.

    나는 우리가 더는 주문 표에 행의 위치가 변경해야하는 경우보다 동일한 (<또는>) 반환과 실제 값을 필요 SQL 테이블에서 실제 다음 또는 이전 행을 가지고 생각합니다.

    우리는 이웃 행을 검색 할 가치 $ 위치를 필요 내 테이블에서 나는 열 '위치'를 만들어

    그리고 필요한 행을 얻기를위한 SQL 쿼리는 다음과 같습니다

    다음에 :

    SELECT * 
    FROM `my_table` 
    WHERE id = (SELECT (id) 
                FROM my_table 
                WHERE position = ($position+1)) 
    LIMIT 1
    

    이전에 :

     SELECT * 
     FROM my_table 
     WHERE id = (SELECT (id) 
                 FROM my_table 
                 WHERE `position` = ($position-1)) 
     LIMIT 1
    
  22. ==============================

    22.foo는에서 상위 1 *을 선택한 경우 ID 오름차순으로 ID> 4 순서

    foo는에서 상위 1 *을 선택한 경우 ID 오름차순으로 ID> 4 순서

  23. from https://stackoverflow.com/questions/1446821/how-to-get-next-previous-record-in-mysql by cc-by-sa and MIT license