Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-查找给定特定WHERE子句的下一行和上一行_Sql_Mysql - Fatal编程技术网

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

SQL-查找给定特定WHERE子句的下一行和上一行,sql,mysql,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

我有一个名为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 这将是topic_id为123的行之前的行,以及该行之后的行

如果在一个查询中很难做到这一点,那么将其分解为两个查询肯定是可以的

我希望避免执行整个SQL查询SELECT*FROM bb_topics,其中topic_poster=5并循环遍历结果,因为结果集有时非常庞大

这可能吗-

注:在否决表决前,请阅读评论和问题的第一次修订-

根据定义,RDBMS表上的数据没有顺序。这意味着在运行查询时,如果不指定ORDERBY子句,则不同查询的顺序可能不同。此外,您还必须考虑到下一个查询将至少返回一个不同的顺序。 假设数据库中的另一个用户插入了一条新记录,并且RDBMS考虑将其放在您正在考虑的行之间。或者DBA在线将表移动到另一个表中,这在Oracle中是可能的,例如,在这种情况下,数据可以在任何事项上更改

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

下一行:

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)
两者:


这里有一个微妙但有效的方法来实现这一点,它甚至可以在不支持子查询的MySQL的旧版本上工作-

这将为您提供下一个相邻的帖子。如果不是不言而喻的,我可以在下一篇文章中填写对称子句

编辑-小调已更正的alii。

也看看这个


我的猜测是,限制为1的并集比我在这里的答案中的聚合更好。

我添加了一个ORDER BY子句来澄清。谢谢我对你投了反对票,因为这是一个简单的查询问题,与记录的排序顺序无关。@cdonner,问题的第一次修订显示了没有排序依据的查询。@FerranB,我知道,但它与此无关。他希望获得给定行的下一行/上一行,而不考虑该行的排序顺序。当然,你可以在内存中的结果集中这样做,那么你是对的——这很重要。但他要的是SQL。@joe_mucchiello,你在吹毛求疵。有一个增加主题ID的隐式顺序。我想他在问题中已经充分解释了这一点。仅供参考SQL分析函数让您使用超前和滞后函数来实现这一点。不确定mySQL是否支持,但SQL2008支持。这很有希望!很抱歉,这个新问题,但是我应该把我知道的主题id放在哪里?另外,它是否从BBU主题中选择*作为t?是的,这可能是正确的。我更熟悉SQL Server语法。让我再为你编辑一次。如果你已经有了当前的主题id和海报id,这就可以了。如le dorfier所示,你也可以在一个带有自连接的查询中做同样的事情,它将在一个查询中为结果集中的每一行提供下一个和上一个id,这要优雅得多。除了他的查询不起作用之外,它将为你提供此海报的所有较高和较低的主题id。您仍然需要在连接条件中使用min和max函数进行子查询。cdonner,这太棒了,谢谢!我确信这在SQL Server中是可行的,但对于MySQL,我认为语法应该是:选择*FROM bb_topics,其中topic_id=SELECT MINtopic_id FROM bb_topics,其中topic_id>123,topic_poster=5这是可行的!:-这是不完全正确的,因为联接将为您提供比您想要的多得多的功能。没有办法绕过子查询。然后我没有正确获得表达式。最多只能有1行具有更高的主题id,并且主题id与目标id之间没有。主题id为NULL表示不匹配。
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)
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