我有一个名为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”)并循环遍历结果,因为结果集有时很大。
这可能吗? : - )
答案 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。