查询下一个/上一个记录

时间:2010-04-02 13:34:00

标签: php sql mysql

  

可能重复:
  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排序,我可以做一些相当简单的事情:

SELECT MIN(news_id) AS next_news_id FROM news WHERE news_id > '$old_news_id' LIMIT 1
SELECT MAX(news_id) AS prev_news_id FROM news WHERE news_id < '$old_news_id' LIMIT 1

但是新闻可以按任何字段排序,而且我不一定知道哪个字段是排序的,所以如果用户对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=n之类的查询字符串,那么是可行的,我可以增加$startpage并将LIMIT $startpage,1添加到查询中。但我有news/news_id-news-title-here这样的网址被重写为?news_id=n,所以我不知道乍一起是什么。即使我这样做了,如果用户通过外部链接到达那里会怎么样?如果在用户阅读当前页面时添加新帖子怎么办?

不要过于拘泥于上面例子的细节,真正的问题是:

给定一个唯一的记录ID和一个任意排序列,是否有办法确定哪些记录会在该特定记录之前和之后立即丢失,而不会遍历整个记录集。

3 个答案:

答案 0 :(得分:0)

为什么你不使用限制?

e.g。你每页列出10项。限制1,10 接下来的10个项目:限制11,10 等等。

无论您是每页显示一个项目还是100个项目,系统始终都是相同的。

编辑:需要更多解释,如果你有一个详细页面,你肯定会通过列表来到它,列表是用一个查询创建的,所以你知道这个列表中的位置,并且可以给这个参数到详细页面。因此,当您有上一个/下一个链接时,您可以调用查询,其限制为1,并且与您的参数的偏移量。

编辑2:您可以使用查询根据您的订单查找行的位置,但这只适用于DESC:

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;

答案 1 :(得分:0)

为什么不对用于news_id的news_author使用相同的方法?

编辑: 有一个陷阱:news_author肯定不是唯一的。因此,您需要按2个字段订购news_author查询:news_author,news_id。因此,您需要2个条件才能获得下一位作者

答案 2 :(得分:0)

伪代码中的

:     $ currentValue =“SELECT $ sort_column FROM news 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"

没有