programing

MySQL에서 다음/이전 레코드를 가져오려면 어떻게 해야 합니까?

kingscode 2022. 9. 8. 22:58
반응형

MySQL에서 다음/이전 레코드를 가져오려면 어떻게 해야 합니까?

ID가 있는 레코드가 있다고 합니다. 3,4,7,9

다음/이전 링크를 통해 네비게이션을 통해 다른 링크로 이동할 수 있도록 하고 싶습니다.

문제는 가장 높은 아이디를 가진 레코드를 가져오는 방법을 모른다는 것입니다.

그래서 신분증이 있는 기록이 있을 때 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)

cemkalyoncu의 솔루션 외에 다음과 같은 것도 있습니다.

다음 레코드:

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

이전 레코드:

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

편집: 이 답변은 최근 몇 가지 업베이트를 받고 있기 때문에 MySQL에서는 나중에 반드시 높은 자동 증분 값을 추가할 필요가 없기 때문에 프라이머리 키 컬럼이 정렬 기준 컬럼이 아님을 이해해야 한다는 에 대해 앞서 말씀드렸던 코멘트를 강조하고 싶습니다.

치 않고, 낮은).id판단하기 위한 레코드가 실제로 나중에 추가되는지(또는 더 일찍 추가되는지) 확인하는 수단으로 사용하지 마십시오.대신 날짜/시간 열을 사용하여 정렬하는 것이 좋습니다.

위의 모든 솔루션에는 2개의 데이터베이스 콜이 필요합니다.아래 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만큼 줄이면 한계문에 넣습니다.예를 들어, 위에서 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을 만들 수 있습니다. 각 하위 쿼리에 다른 @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)

다음 줄

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

저도 댄과 같은 문제가 있어서 댄의 대답을 이용해서 개선했어요.

먼저 행 인덱스를 선택합니다.여기에는 차이가 없습니다.

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-statement를 사용할 수 있습니다.어쨌든 이전 기록은 없으니 아무 것도 선택하지 마세요.마지막 기록의 경우 다음 행이 있으므로 결과가 없습니다.

또한 주문에 ASC가 아닌 DESC를 사용하는 경우 다음 행과 이전 행을 선택하기 위한 쿼리는 동일하지만 전환됩니다.

이것은, 보다 같은 결과를 가지는 조건의 범용 솔루션입니다.

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

여기서는 단일 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) )

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;
  }
}

하나의 쿼리만 사용하도록 @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

CurrentArticle 변경다음과 같은 현재 기사 ID를 가진 ID

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

@row trick과 유사한 변수를 사용하여 원하는 순서를 사용하여 이전 행의 열을 표시할 수 있는 다른 방법이 있습니다.

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: 이것이 정의된 행동인지는 모르겠지만, 저는 그것을 사용해봤고 효과가 있습니다.

이상의 쿼리를 입력하고next_id그든 、 을을.........

「」의 할당cur_id에 입력한 후하여 ""를 가져옵니다.next_id fieldselect를 합니다.에 그냥 .next_id.

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

인덱스 열(예: id)이 있는 경우 1개의 SQL 요청에서 이전 ID와 다음 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

제 대답은 이렇습니다.'Decent Dabbler'에서 아이디어를 얻어 id가 min(id)에서 max(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

테이블에서 다음 ID와 이전 ID를 가져오고 다음 ID가 없는 경우 첫 번째 ID를 선택합니다.이전 ID와 동일합니다.

SELECT id FROM foo
    WHERE ( 
    id = IFNULL((SELECT min(id) FROM medialibrary WHERE id > ?),(SELECT id FROM foo LIMIT 1)) 
    or 
    id = IFNULL((SELECT max(id) FROM medialibrary WHERE id < ?),(SELECT id FROM fooORDER BY id DESC LIMIT 1))

다음 레코드와 미리 보기 레코드를 얻기 위한 솔루션, 마지막 레코드의 경우 첫 번째 레코드로 되돌아가기 위한 솔루션 및 그 반대도 마찬가지입니다.

아이디를 사용하지 않고 멋진 url의 제목을 사용하고 있습니다.

코드 시그니터 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;
    }     
}

100% 동작

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

SQL 테이블에서 실제 다음 행 또는 이전 행을 사용하려면 동일한 값을 가진 실제 값이 필요합니다. 주문 테이블에서 행의 위치를 변경해야 할 경우 (< 또는 >) 여러 개가 반환됩니다.

우리는 가치가 필요하다$position검색하다neighbours테이블에 '위치' 열을 만들었습니다.

필요한 행을 취득하기 위한 SQL 쿼리는 다음과 같습니다.

next의 경우:

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

foo에서 top 1 * 를 선택합니다.id > 4 order by id asc

언급URL : https://stackoverflow.com/questions/1446821/how-to-get-next-previous-record-in-mysql

반응형