热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在MySQL中获取下一个/上一个记录?-Howtogetnext/previousrecordinMySQL?

SayIhaverecordswithIDs3,4,7,9andIwanttobeabletogofromonetoanotherbynavigationvi

Say I have records with IDs 3,4,7,9 and I want to be able to go from one to another by navigation via next/previous links. The problem is, that I don't know how to fetch record with nearest higher ID.

假设我有id 3,4,7,9的记录,我希望能够通过导航通过next/previous链接从一个到另一个。问题是,我不知道如何用最近的更高的ID获取记录。

So when I have a record with ID 4, I need to be able to fetch next existing record, which would be 7. The query would probably look something like

当我有一个ID 4的记录时,我需要能够获取下一个已有的记录,也就是7。查询可能看起来是这样的

SELECT * FROM foo WHERE id = 4 OFFSET 1

How can I fetch next/previous record without fetching the whole result set and manually iterating?

如何在不获取整个结果集和手动迭代的情况下获取下一个/上一个记录?

I'm using MySQL 5.

我使用的是MySQL 5。

20 个解决方案

#1


201  

next:

下一个:

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

previous:

前一:

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

#2


123  

In addition to cemkalyoncu's solution:

除了cemkalyoncu的解决方案:

next record:

下一个记录:

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

previous record:

之前的记录:

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

edit: Since this answer has been getting a few upvotes lately, I really want to stress the comment I made earlier about understanding that a primary key colum is not meant as a column to sort by, because MySQL does not guarantee that higher, auto incremented, values are necessarily added at a later time.

编辑:因为这个答案最近得到了几个问题,我想强调了解早些时候评论我,主键科勒姆并不意味着列排序,因为MySQL不保证高,汽车增加,值必然是添加在稍后的时间。

If you don't care about this, and simply need the record with a higher (or lower) id then this will suffice. Just don't use this as a means to determine whether a record is actually added later (or earlier). In stead, consider using a datetime column to sort by, for instance.

如果您不关心这个,并且只需要id更高(或更低)的记录,那么这就足够了。只是不要把它作为一种手段来确定是否稍后(或更早)添加记录。相反,可以考虑使用datetime列进行排序。

#3


47  

All the above solutions require two database calls. The below sql code combine two sql statements into one.

所有上述解决方案都需要两个数据库调用。下面的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


15  

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

#5


9  

I was attempting to do something similar to this, but I needed the results ordered by date since I can't rely on the ID field as a sortable column. Here's the solution I came up with.

我试图做一些类似的事情,但是我需要日期排序,因为我不能依赖ID字段作为一个可排序的列。这是我想到的解决办法。

First we find out the index of the desired record in the table, when it's sorted as we want:

首先,我们在表中找到所需记录的索引,按我们的要求排序:

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;

Then decrement the result by 2 put it in the limit statement. For example the above returned 21 for me so I run:

然后把结果减2代入极限语句。举个例子,上面的21是我的,所以我跑:

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

Gives you your primary record along with it's next and previous records given your stated order.

给你的主要记录,连同它的下一个和以前的记录给你指定的订单。

I tried to do it as a single database call, but couldn't get the LIMIT statement to take a variable as one of it's parameters.

我尝试把它作为一个数据库调用来做,但是无法得到将变量作为参数之一的LIMIT语句。

#6


5  

Try this example.

试试这个例子。

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 ASC LIMIT 1) as next_name
FROM student s
    WHERE id = 7; 

Note: If value is not found then it will return null.

注意:如果没有找到值,它将返回null。

In the above example, Previous value will be Raja and Next value will be null because there is no next value.

在上面的示例中,前一个值将是Raja,下一个值将为null,因为没有下一个值。

#7


4  

Using @Dan 's approach, you can create JOINs. Just use a different @variable for each sub query.

使用@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


3  

Next row

下一行

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

Previous row

前一行

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

sample next row

样本下一行

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

sample previous row

样品之前的行

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


3  

I had the same problem as Dan, so I used his answer and improved it.

我和丹有同样的问题,所以我用了他的答案并加以改进。

First select the row index, nothing different here.

首先选择行索引,这里没有什么不同。

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;

Now use two separate queries. For example if the row index is 21, the query to select the next record will be:

现在使用两个独立的查询。例如,如果行索引是21,那么选择下一个记录的查询将是:

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

To select the previous record use this query:

要选择先前的记录,请使用以下查询:

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

Keep in mind that for the first row (row index is 1), the limit will go to -1 and you will get a MySQL error. You can use an if-statement to prevent this. Just don't select anything, since there is no previous record anyway. In the case of the last record, there will be next row and therefor there will be no result.

记住,对于第一行(行索引为1),限制将变为-1,您将会得到一个MySQL错误。可以使用if语句来防止这种情况。不要选择任何东西,因为之前没有记录。在最后一个记录的情况下,将会有下一行,因此没有结果。

Also keep in mind that if you use DESC for ordering, instead of ASC, you queries to select the next and previous rows are still the same, but switched.

还要记住,如果您使用DESC进行排序,而不是使用ASC,那么您选择下一行和前一行的查询仍然是相同的,但是已经切换了。

#10


2  

How to get next/previous record in MySQL & PHP?

如何在MySQL和PHP中获得下一个/以前的记录?

My example is to get the id only

我的例子是只获取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;
  }
}

#11


2  

This is universal solution for conditions wiht more same results.

这是对更多相同结果的条件的普遍解。

BUTTON_PREVIOUS";
if ($current_row[$yid+1]) $out_button.= "BUTTON_NEXT";

echo $out_button;//display buttons
?>

#12


1  

Here we have a way to fetch previous and next records using single MySQL query. Where 5 is the id of current record.

在这里,我们有一种使用单个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) )

#13


0  

There's another trick you can use to show columns from previous rows, using any ordering you want, using a variable similar to the @row trick:

您还可以使用另一个技巧来显示前几行中的列,使用任何您想要的排序,使用类似于@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

Apparently, the select columns are evaluated in order, so this will first select the saved variables, and then update the variables to the new row (selecting them in the process).

显然,select列是按顺序计算的,所以这将首先选择保存的变量,然后将变量更新到新的行(在过程中选择它们)。

NB: I'm not sure that this is defined behaviour, but I've used it and it works.

NB:我不确定这是一种固定的行为,但我已经用过它了,它确实有效。

#14


0  

If you want to feed more than one id to your query and get next_id for all of them...

如果您希望向查询提供多个id,并为所有id获取next_id……

Assign cur_id in your select field and then feed it to subquery getting next_id inside select field. And then select just next_id.

在选择字段中分配cur_id,然后将其提供给获取select字段中的next_id的子查询。然后选择next_id。

Using longneck answer to calc next_id:

使用长颈回答calc 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;

#15


0  

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

#16


0  

If you have an index column, say id, you can return previous and next id in one sql request. Replace :id with your value

如果您有一个索引列,比如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

#17


0  

My solution to get the next and previews record also to get back to the first record if i'm by the last and vice versa

我的解决方案是获得下一个和预览记录,如果我是最后一个,反之亦然。

I'm not using the id i'm using the title for nice url's

我没有使用id,我用的是url的标题。

I'm using Codeigniter HMVC

我使用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;
    }     
}

#18


0  

Optimising @Don approach to use only One Query

优化@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

change CurrentArticleID with current article ID like

用当前文章ID来更改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

#19


-1  

Select top 1 * from foo where id > 4 order by id asc

从foo中选择top 1 *, id为> 4,id为asc。

#20


-2  

I think to have the real next or previous row in SQL table we need the real value with equal, () return more than one if you need to change position of row in a ordering table.

我认为要获得SQL表中真正的下一行或前一行,我们需要具有相等的实值,( <或> )如果需要更改排序表中的行位置,则返回多个值。

we need the value $position to search the neighbours row In my table I created a column 'position'

我们需要$position值来搜索表中的邻居行我创建了一个列" position "

and SQL query for getting the needed row is :

而获取所需行的SQL查询为:

for next :

下:

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

for previous:

前一:

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

推荐阅读
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
author-avatar
永城之家_319
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有