我正在建立一个简单的论坛。我需要显示的是一个包含最新主题的列表,并且每个主题附近都是最新的回复/帖子。类似的东西:
Topic name: | Last reply:
Topic name 1 here | 2013-02-01 by username1
Topic name 2 here | 2013-01-01 by username2
etc.
问题是主题和回复都在同一个名为'pages'的表中。 该表有一个字段模板,当然包含表'模板'的ID。
因此,我只需通过Template.name连接模板并过滤记录“论坛主题”
这将返回所有主题。因为我还需要每个主题的最新回复,所以我决定在同一个模板上使用过滤器做一个子查询但是现在用于记录'论坛回复'并且由Reply.date DESC和LIMIT 1命令,它返回最新的回复这个话题。现在是时候显示我当前的查询适用于包含至少1个回复的主题:
/*----some fields to return----*/
SELECT TopicContent.title, ReplyContent.title, Reply.date, Reply.id,
(
/*----subquery to return latest reply id used inside HAVING later on----*/
SELECT Reply.id
FROM pages AS Reply
INNER JOIN templates AS Template ON Reply.template = Template.id
WHERE Reply.parent_id = Topic.id
AND Template.name = 'Forum reply'
ORDER BY Reply.date DESC
LIMIT 1
) AS reply_id
FROM pages AS Topic
INNER JOIN templates AS Template ON Topic.template = Template.id
INNER JOIN page_content AS TopicContent ON Topic.id = TopicContent.page
/*----left join used because topic could have zero replies if new----*/
LEFT JOIN pages AS Reply ON Topic.id = Reply.parent_id
LEFT JOIN page_content AS ReplyContent ON Reply.id = ReplyContent.page
WHERE Template.name = 'Forum topic'
HAVING Reply.id = reply_id
/*--------------------------------------------------------------------------------*/
/*----HAVING | returns not all topics but with correct latest reply----*/
/*----GROUP BY Topic.id | returns topics correctly but incorrect latest reply-----*/
现在最重要的是,如果提交了新的主题,它还不包含任何回复。
所以当我使用HAVING时,它只返回包含至少一个回复的主题。 使用GROUP BY时,它不会返回包含一个或多个回复的主题的最新回复。对于不包含回复的主题,它返回NULL,这很好。
我需要更改JOINS吗?任何想法来解决这个问题。非常感谢!
答案 0 :(得分:1)
我将MaxId子查询移动到from子句,因为您使用GROUP BY的方式不适用于您尝试执行的操作。在这里,您只需将结果集加入到检索MaxId字段的子查询中。
SELECT
*
FROM
pages
.
.
.
LEFT OUTER JOIN
(
SELECT
ReplyId As [MaxId],
p.Template
FROM
Pages p INNER JOIN Templates t ON p.Template = t.Id
WHERE
TemplateName = 'Forum Reply'
ORDER BY ReplyDate LIMIT 1
) a ON a.Template = pages.Template
WHERE
Template.name = 'Forum topic'
或者(如果多个第一次回复具有完全相同的时间,则可以给您多个回复,在这种情况下您可以限制结果)
SELECT
*
FROM
pages
.
.
.
(SELECT
ReplyId As [MaxiId],
Template
FROM
Pages p INNER JOIN
Templates t ON p.Template = t.id LEFT OUTER JOIN
(SELECT
p.Template,
MIN(ReplyDate) AS [FirstReplyDate]
FROM
Pages p INNER JOIN
Templates t ON p.Template = t.id
WHERE
TemplateName = 'Forum Reply'
GROUP BY
p.Template) b ON b.Template = t.id
WHERE
p.ReplyDate = b.FirstReplyDate
) a ON a.Template = pages.Template
无论哪种方式,您都应该将第一个回复子查询移动到From子句
答案 1 :(得分:0)
这还不是答案,而是要求海报提供更多信息,但因为评论太长,我会在这里发帖。
从您的查询中,我可以得出结论,您的表格看起来像这样
templates(id, name)
pages(id, parent_id, date, template)
page_contents(page, title)
pages
存储帖子的结构,page_contents
存储帖子的内容,template
确定帖子的类型。我是对的吗?
问题:
parent_id
应该是主题的ID。但是,主题不在任何主题下,所以基本上,它应该是0或NULL,是不是?