2010-04-02 4 views
0

가능한 중복 :
What is the SQL for 'next' and 'previous' in a table?쿼리 이전/다음 기록

나는 테이블에서 다음 또는 이전 기록을 얻을 수있는 더 좋은 방법을 찾기 위해 노력하고있어.

:

CREATE TABLE news (
    news_id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    news_datestamp DATETIME NOT NULL, 
    news_author VARCHAR(100) NOT NULL, 
    news_title VARCHAR(100) NOT NULL, 
    news_text MEDIUMTEXT NOT NULL 
); 

지금 프론트 엔드에 내가 news_id으로 분류하고있어, 난 같은 비교적 간단 뭔가를 할 수 있으며, 다음 또는 이전 레코드 탐색 버튼을 원하는 :의 나는 블로그 또는 뉴스 테이블이 있다고 가정 해 봅시다

그러나 뉴스는 모든 필드별로 정렬 할 수 있으며 어떤 필드가 정렬되어 있는지 반드시 알 필요는 없습니다. 예를 들어 사용자가 news_author과 같은 정렬을하면이 기능이 작동하지 않습니다.

나는 필자가 필요로하는 레코드를 찾을 때까지 전체 테이블을 정렬하고 모든 레코드를 루핑하는 오히려 못 생기고 비효율적 인 방법을 사용했습니다.

$res = mysql_query("SELECT news_id FROM news ORDER BY `$sort_column` $sort_way"); 
$found = $prev = $next = 0; 
while(list($id) = mysql_fetch_row($res)) { 
    if($found) { 
     $next = $id; 
     break; 
    } 
    if($id == $old_news_id) { 
     $found = true; 
     continue; 
    } 
    $prev = $id; 
} 

더 나은 방법이 있어야합니다.

편집, 설명 :

제한을 사용하지 않는 이유는 무엇입니까? 나는 현재 레코드의 결과 세트에서의 위치를 ​​알아야 할 것입니다. 이게 당신의 전형적인 페이지 매김이라면, 나는 과 같은 질의 문자열을 가질 수 있습니다. 그래야 $startpage을 증가시키고 LIMIT $startpage,1을 쿼리에 추가 할 수 있습니다. 하지만 ?news_id=n으로 다시 작성되는 news/news_id-news-title-here과 같은 URL이 있으므로 시작 페이지가 무엇인지 알 수 없습니다. 내가 그랬더라도, 사용자가 외부 링크를 통해 거기에 도착한다면 어떨까요? 사용자가 현재 페이지를 읽는 동안 새 게시물이 추가되면 어떻게 될까요?

너무 위의 예제의 세부 사항에 집착하지 마세요, 진짜 질문은 이것이다 : 고유 레코드 ID 및 임의의 정렬 열을 감안할 때

, 기록이 바로 가을을 결정하는 방법이 그 특정 레코드 전후에, 전체 레코드 세트를 루핑하지 않고.

+0

그냥 궁금합니다. 주사에서 $ sort_column을 보호 할 수있는 것이 있습니까? –

+0

@Shrapnel, yes ... 위의 예는 가상의 예제이지만 실제 코드에서는 유효하고 정렬 가능한 열 배열'$ sort_column = (in_array ($ sort_column, $ valid_columns))에 대해'$ sort_column'을 검증하겠습니까? $ sort_column : $ default_sort_column; ' – Rob

+0

내 대답에 편집 참조하십시오 – Rufinus

답변

0

한계를 사용하지 않는 이유는 무엇입니까?

당신은 페이지 당 10 항목을 나열합니다. 다음 10 개 항목 제한 : 1,10 : 한도 11,10 등 제한.

페이지 당 하나 또는 100 개의 항목을 표시하더라도 시스템은 항상 동일합니다.

EDIT : 더 자세한 설명이 필요합니다. 세부 정보 페이지가 있으면 가장 확실하게 목록을 통해 올 것이며, 목록은 특정 검색어로 작성되므로이 목록의 위치를 ​​알 수 있으며이 정보를 제공 할 수 있습니다. param을 세부 정보 페이지로 가져옵니다. 그래서 prev/next 링크가있을 때, 당신은 1의 한계와 당신의 매개 변수로부터의 오프셋을 가지고 질의를 호출 할 수 있습니다.

편집 2 : 당신은 당신의 순서에 따라 행의 위치를 ​​찾기 위해 쿼리를 사용할 수 있지만 이것은 단지 DESC 작동합니다 : 당신이 news_author에 대해 동일한 방법을 사용하지 않는 이유

SELECT COUNT(*)+1 FROM news ma JOIN news mp ON (mp.$sort_column, mp.news_id) > (ma.$sort_column, ma.news_id) WHERE ma.news_id = $news_id; 
+0

특정 레코드를 표시하는 데 한계를 사용할 수 없습니다. URL은 항상 같아야합니다. 절대가 아닌 상대. 따라서, id가 아닌 id 여야합니다. –

+0

이렇게하려면 결과 세트에서 현재 레코드의 위치를 ​​먼저 알아야합니다. 그렇지 않습니다. 나는'news_id' 만 알기 때문에 전체 결과 집합을 반복하고 경기를 찾을 때까지 위치를 계산해야합니다. – Rob

+0

내 게시물을 편집하십시오. 롭은 내가 의미하는 바를 이해하는 것 같다. 신경 쓰지는 마시고, 맹세코, 모든 항목을 반복하면서 혼합 분류 작업을하지 마십시오. 필자는 newsitem의 오프셋을 param으로 저장하고 prev/next 링크로만 사용할 수 있거나 목록 쿼리 부분을 저장하여 세부 정보 페이지의 위치를 ​​찾아야 만합니다. – Rufinus

0

news_id에 사용하셨습니까?

편집 : 하나의 함정이 있습니다. news_author은 고유하지 않습니다. 따라서 news_author, news_id의 두 필드로 news_author 쿼리를 주문해야합니다. 그래서, 당신은 의사 코드에 다음 저자에게

+0

흠, 나는'MIN'과'MAX'가'VARCHAR' 필드에서 작동하지 않을 것이라고 생각 했었습니다. – Rob

+0

@Rob, Ah 나는 그것을 알아 차리지 못했습니다. 그러나 당신은 min과 max가 하나의 행으로 만 구성된 집합에 필요 없다 :) 단지'select news_id ...' –

0

를 얻기 위해이 조건이 필요합니다 $ CurrentValue에는 = "뉴스 FROM $ 열 _ 정렬을 선택 WHERE news_id = $ current_news_id LIMIT 1"

$operator = ($sort_way == 'ASC')?' > ':' < '; 

$nextNewsId = "SELECT news_id FROM news WHERE $sort_column $operator $currentValue ORDER BY $sort_column $sort_way LIMIT 1" 

없음?