从数据库获取上一个和下一个记录并循环它们

时间:2019-05-20 16:04:17

标签: mysql sql

我有一个ID为1到8的表。我想要这样的东西

  

如果我4岁,我应该得到3,5

     

如果我上1,我应该得到8,2

     

如果在8点上,我应该得到7、1

基本上遍历表记录

这是我当前的代码

-- previous or last, if there is no previous
SELECT *
FROM news
WHERE id < 1 OR id = MAX(id)
ORDER BY id DESC
LIMIT 1

-- next or first, if there is no next
SELECT *
FROM news
WHERE id > 1 OR id = MIN(id)
ORDER BY id ASC
LIMIT 1

但是它说组功能的无效使用。有帮助吗?

3 个答案:

答案 0 :(得分:1)

如果id是连续的,则可以执行以下操作:

SQL DEMO

SELECT o.id, 
       COALESCE(b.id, (SELECT MAX(ID) FROM Table1)) as before_id,
       COALESCE(a.id, (SELECT MIN(ID) FROM Table1)) as after_id
FROM Table1 o
LEFT JOIN Table1 b
  ON o.id = b.id + 1
LEFT JOIN Table1 a  
  ON o.id = a.id - 1
ORDER BY o.id  

输出

| id | before_id | after_id |
|----|-----------|----------|
|  1 |         8 |        2 |
|  2 |         1 |        3 |
|  3 |         2 |        4 |
|  4 |         3 |        5 |
|  5 |         4 |        6 |
|  6 |         5 |        7 |
|  7 |         6 |        8 |
|  8 |         7 |        1 |

如果id不是连续的,则需要使用row_number()(mysql ver 8+)或会话变量来创建序列。

答案 1 :(得分:1)

我猜您想在用户查看新闻文章时显示“上一个”和“下一个”按钮。当您获取商品数据时,我将在主查询中获得上一个和下一个ID:

select n.*, -- select columns you need
  coalesce(
    (select max(n1.id) from news n1 where n1.id < n.id ),
    (select max(id) from news)
  ) as prev_id,
  coalesce(
    (select min(n1.id) from news n1 where n1.id > n.id ),
    (select min(id) from news)
  ) as next_id
from news n
where n.id = ?

db-fiddle demo

现在,您可以将prev_idnext_id用于按钮,或通过简单的select * from news where id = ?查询来预取相应的文章。

答案 2 :(得分:0)

您可以删除方法中的过滤条件,并向ORDER BY添加逻辑:

(SELECT n.*
 FROM news
 ORDER BY (id < 1), id DESC
 LIMIT 1
) UNION ALL
(SELECT n.*
 FROM news
 ORDER BY (id > 1), id ASC
 LIMIT 1
) ;

如果您希望将id值放在一行中,则可以使用聚合:

select coalesce(max(case when id < 1 then id end), max(id)) as prev_id,
       coalesce(min(case when id > 1 then id end), min(id)) as next_id
from news n;

在两种情况下,1是示例ID,并且“ 1”可以替换为任何值。