MySQL查询、加入和我自己,或者我总是如何艰难地度过难关

MySQL查询、加入和我自己,或者我总是如何艰难地度过难关,sql,mysql,outer-join,Sql,Mysql,Outer Join,我正在创建一个小论坛 正在尝试运行选择。。。加入…query-too获取个人帖子的信息,以及最后的回复(如果有)。作为我努力做每件事的愿望的一部分,这包括五个表(仅列出与此问题相关的列) 现在,返回主题帖子。假设我有两个,它返回两个都很好。假设我对第一个有八个回复,它将返回9个条目(主题+回复各一个,没有回复的单个条目)。因此,我想我的问题是:我不知道如何将finalLEFT-OUTER-JOIN子句中的返回数限制为最近的返回数,或者干脆将最近的返回数从窗口中删除 (是的,我意识到,orderb

我正在创建一个小论坛

正在尝试运行
选择。。。加入…
query-too获取个人帖子的信息,以及最后的回复(如果有)。作为我努力做每件事的愿望的一部分,这包括五个表(仅列出与此问题相关的列)

现在,返回主题帖子。假设我有两个,它返回两个都很好。假设我对第一个有八个回复,它将返回9个条目(主题+回复各一个,没有回复的单个条目)。因此,我想我的问题是:我不知道如何将final
LEFT-OUTER-JOIN
子句中的返回数限制为最近的返回数,或者干脆将最近的返回数从窗口中删除

(是的,我意识到,
orderby…
子句很混乱,因为它会先按创建后的日期排序,然后按注释创建日期排序。是的,我意识到我可以通过在postinfo中添加两个字段来简化我的所有问题,即lastCommentCreate和lastCommentCreateID,并在每次回复时更新它,但是……我喜欢这种艰难的方式。))

那么我做错了什么


或者这是一个空洞的问题,我应该被带到“木棚周围,用锤子敲打”

看起来最后一个左连接是唯一可以返回多行的连接。如果是这样,您可以使用限制5来获取最后五条注释:

 ORDER BY t5.create DESC
 LIMIT 5
如果不是,一个非常简单的解决方案是使用单独的查询检索注释:

SELECT *
FROM rantCommentInfo t5
    ON t5.referenceType = 8 
    AND t5.referenceid = t1.id
LEFT OUTER JOIN rantUser t6
    ON t6.id = t5.authorID
ORDER BY CommentCreate
WHERE t5.referenceid = YourT1Id
LIMIT 5

在一个查询中,如果没有行号,我想不出一种方法来完成它,而MySQL不支持行号。

post
postInfo
,以及
用户
用户信息
表之间的分离,在这里似乎没有做什么,只是混淆了一些事情。为了更好地看到解决方案,让我们把事情归结到它们的本质上注释:一个表
Posts
(主键
id
,创建日期
date
,以及其他字段)和一个表
Comments
(主键
id
,外键
refId
引用
Posts
,唯一的创建日期
date
,以及其他字段);我们希望看到所有帖子,每个帖子都有最新的评论(如果有的话)(检索到的表行的主键
id
和其他字段当然可以在
SELECT
中上下文使用,以获取和显示更多信息,但这不会改变核心结构,简化核心结构有助于说明解决方案)。我假设一条评论的创建日期是唯一的,否则“最新评论”可能会模棱两可(当然,这种模棱两可可以通过其他方式任意截断,从“最新评论”集合中选择一项发送给给定的帖子)

因此,这里有一种方法:

SELECT Posts.id, Comments.id FROM Posts
LEFT OUTER JOIN Comments on (Posts.id = Comments.refId)
WHERE Comments.create IS NULL OR (
      Comments.create = (SELECT create FROM Comments
                         WHERE refID = Posts.id
                         ORDER BY create DESC
                         LIMIT 1)
) /* add ORDER BY &c to taste;-) */

想法:对于每个帖子,我们需要一个“空注释”(当没有注释时),或者是创建日期在引用帖子的人中最高的注释;这里,内部
SELECT
负责查找“最高”的创建日期。因此,本着同样的精神,内部SELECT可能是
SELECT MAX(create)从refID=Posts.id的评论来看,这可能更可取(更短、更直接,可能更快)。

很抱歉,这是为了显示主题及其最后回复的索引(因此默认限制为0,25)。这个想法有其优点,而且可能是迄今为止我发现的最接近解决方案的:运行一个单独的查询,将这些结果添加到包含原始信息的数组中,然后在它们显示之前使用一些巧妙的排序技巧。这将给你排名前1的注释,但他正在寻找排名前5的注释?不,我只需要排名前1的注释。我是u唱五张表使之成为可能(虽然他的,我将用3张表进行测试,虽然他的礼物2。在创建日期添加额外的左外连接并不太难。@Nikolai Echternatht:啊,好吧,我误解了这个问题。这个答案将适用于前1条评论。我会投票支持:如果你需要“前5”,那么你将使用我发布了“main form”(但限制为5),并在嵌套SELECT左侧的IN而不是=中,即top 1或top 5,更改很小。@Alex Martelli:MySQL不支持IN子查询中的限制(请尝试)。您可以使用子查询来解决此问题,但不允许您引用回Posts表。
SELECT *
FROM rantCommentInfo t5
    ON t5.referenceType = 8 
    AND t5.referenceid = t1.id
LEFT OUTER JOIN rantUser t6
    ON t6.id = t5.authorID
ORDER BY CommentCreate
WHERE t5.referenceid = YourT1Id
LIMIT 5
SELECT Posts.id, Comments.id FROM Posts
LEFT OUTER JOIN Comments on (Posts.id = Comments.refId)
WHERE Comments.create IS NULL OR (
      Comments.create = (SELECT create FROM Comments
                         WHERE refID = Posts.id
                         ORDER BY create DESC
                         LIMIT 1)
) /* add ORDER BY &c to taste;-) */