0

我正在创建一个小型论坛。

尝试运行SElECT... JOIN...查询也会获取有关各个帖子的信息,以及最后的回复(如果有)。作为我希望以艰难的方式完成所有事情的一部分,这涵盖了五个表格(仅说明了与此问题相关的列)

评论信息参考ID | 参考类型 | 作者ID | 创造
邮政编码 | 标题
postitInfo 参考PostitID | 创建 | 作者ID
用户名 | 用户名 | 允许
用户信息参考用户ID | 标题

因此,我运行此查询SELECT... JOIN...查询以获取最新的主题及其最后的回复。

SELECT DISTINCT
    t1.id, t1.title, t2.create, t2.lastEdit, t2.authorID, t3.username, 
    t4.title AS userTitle, t3.permission, t5.create AS commentCreate, 
    t5.authorID AS commentAuthor, t6.username AS commentUsername, 
    t6.permission AS commentPermission
FROM rantPostit AS t1
LEFT JOIN (rantPostitInfo AS t2) 
    ON ( t1.id = t2.referencePostitID)
LEFT OUTER JOIN (rantUser as t3, rantUserInfo as t4) 
    ON (t2.authorId = t3.id AND t4.referenceUserId = t2.authorId)
LEFT OUTER JOIN (rantCommentInfo as t5, rantUser as t6) 
    ON (t5.referenceType = 8 AND t5.referenceID = t1.id AND t6.id = t5.authorID)
ORDER BY t2.create DESC, t5.create DESC

现在,这将返回主题帖子。假设我有两个,它返回它们都很好。假设我对第一个有 8 个回复,它将返回 9 个条目(主题 + 回复各一个,没有回复的单个条目)。所以,我想我的问题是这样的:我不知道该怎么做才能将最后LEFT OUTER JOIN条款中的退货数量限制为最近的,或者只是将最近的退货数量排除在窗口之外。

(是的,我意识到该ORDER BY...子句搞砸了,因为它会首先按帖子创建日期排序,然后按评论创建日期排序。是的,我意识到我可以通过在 postitInfo 中添加两个字段来简化所有问题,lastCommentCreate 和lastCommentCreateID,并在每次回复时更新它,但是......我喜欢这种艰难的方式。)

那么我做错了什么?

或者这是一个如此愚蠢的问题,我应该被带到木棚周围并用锤子敲打?

4

2 回答 2

1

postandpostInfouserand表之间的拆分userInfo似乎在这里除了混淆之外没有任何作用。为了更好地了解解决方案,让我们归结为它们的本质:一张表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 MAX(create) FROM Comments WHERE refID = Posts.id更可取(更短、更直接,而且可能更快)。

于 2009-05-23T22:07:08.293 回答
0

看起来最后一个 LEFT JOIN 是唯一可以返回多行的。如果这是真的,您可以使用 LIMIT 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

想不出在一个查询中没有 ROW_NUMBER 的方法,这是 MySQL 不支持的。

于 2009-05-23T21:42:39.620 回答