SQL - 在给定特定WHERE子句的情况下查找下一行和上一行

时间:2009-03-14 00:50:46

标签: sql mysql

我有一个名为bb_posts的MySQL表,由bbPress论坛使用。它有一个名为topid_id的自动增量字段和另一个名为topic_poster的字段。

我正在尝试编写一个找到“同一作者的下一篇文章”的函数。因此,例如,假设用户位于显示主题123的特定页面上。如果您执行SQL查询:

SELECT *
FROM `bb_topics`
WHERE `topic_poster` = 5
ORDER BY `topic_id` ASC

这可能会返回以下行:

topic_id    topic_poster
6           5
50          5
123         5
199         5
2039        5

我想要做的是编写一个返回这两行的SQL查询:

topic_id    topic_poster
50          5
199         5

这将是主题为行的行,主题为123,行为行后的行。

如果在一个查询中执行此操作太难了,那么将其分解为两个查询绝对可以......

我想避免执行整个SQL查询(“SELECT * FROM bb_topics WHERE topic_poster = 5”)并循环遍历结果,因为结果集有时很大。

这可能吗? : - )

4 个答案:

答案 0 :(得分:14)

下一个:

SELECT * FROM `bb_topics` 
      WHERE `topic_id` = 
      (select min(`topic_id`) FROM `bb_topics` where `topic_id` > 123
         and `topic_poster` = 5)

上一篇:

SELECT * FROM `bb_topics` 
      WHERE `topic_id` = 
      (select max(`topic_id`) FROM `bb_topics` where `topic_id` < 123
         and `topic_poster` = 5)

这两种:

SELECT * FROM `bb_topics` 
      WHERE `topic_id` = 
      (select min(`topic_id`) FROM `bb_topics` where `topic_id` > 123
                     and `topic_poster` = 5)
      or `topic_id` = 
      (select max(`topic_id`) FROM `bb_topics` where `topic_id` < 123
                        and `topic_poster` = 5)

答案 1 :(得分:2)

同样看看older question

我的猜测是,带有LIMIT 1的UNION比我在这里的答案中的聚合表现更好。

答案 2 :(得分:0)

注意:在downvoting之前,请阅读评论和问题的第一个修订版; - )

根据定义,RDBMS表上的数据未按顺序排列。这意味着当您运行查询时,如果未指定ORDER BY子句,则顺序可以从一个查询到另一个查询不同。此外,您必须考虑下一个查询将(或者至少可能)返回不同的订单

假设可能是数据库中的另一个用户插入新记录,并且RDBMS认为将它放在您正在考虑的行之间。或者DBA在线基础上将表格移动到另一个表格(例如,在Oracle中可以这样做),在这种情况下,可以在任何事情上更改数据。

对于您的问题,您必须构建一种查询结果缓存,以确定查询的上一行和下一行。

答案 3 :(得分:0)

这是实现这一目标的一种微妙但有效的方法,它甚至适用于不支持子查询的旧版MySQL -

  
SELECT *    
FROM bb_topics AS bb1    
LEFT JOIN bb_topics AS bb2    
    ON bb1.topic_poster = bb2.topic_poster    
    AND bb2.topic_id > bb1.topic_id    
LEFT JOIN bb_topics AS bb3  
    ON bb1.topic_poster = bb3.topic_poster    
    AND bb3.topic_id > bb1.topic_id    
    AND bb3.topic_id < bb2.topic_id  
WHERE bb1.topic_poster = 5  
    AND bb3.topic_id IS NULL  
  

这会让你获得下一个相邻的帖子。如果不明确的话,我可以填写下一篇文章的对称条款。

编辑 - 小修正alii。