我正在尝试制作一个简单的讨论板,因此我需要与他们的作者和主题作者的主题标题最后的帖子。
到目前为止,我有这个
SELECT
`t`.`id`,
`t`.`title`,
`t`.`date` as theme_date,
`u`.`id` as user_id,
`u`.`username` as user_username,
COUNT(p.id) as count_posts,
SUBSTRING_INDEX(GROUP_CONCAT(`p`.`id` ORDER BY `p`.`id` DESC SEPARATOR "| " ), "| ", 1) as last_post_id,
SUBSTRING_INDEX(GROUP_CONCAT(`p`.`date` ORDER BY `p`.`id` DESC SEPARATOR "| " ), "| ", 1) as last_post_date,
IFNULL(MAX(p.date), t.date) AS pts
FROM
`topics` t
LEFT JOIN
`posts` p ON `p`.`topics_id` = `t`.`id`
LEFT JOIN
`users` u ON `u`.`id` = `t`.`user_id`
GROUP BY
`t`.`id`
ORDER BY
`pts` DESC
LIMIT 10
我在这里有10个最新的主题标题,他们的作者用户名和ID,每个主题中的消息数,每个主题的最后ID和发布日期,以及按活动排序的所有内容......基本上所有内容。我需要的只是作者最后帖子的用户名。我想我必须使用子查询进行一次左连接,但我有点卡住了。 有人能帮助我吗?
答案 0 :(得分:1)
而不是形成包含整个帖子的帖子的串联的字符串,然后从中获取第一个子字符串(由id
排序),这不仅是性能拖累(因为它不可思议并且需要昂贵的字符串操作)但也受到错误的影响(如果分隔符恰好出现在连接的字符串中,或者连接的结果超出MySQL的限制)...
您真正想做的是获取groupwise maximum,这可以通过将posts
表与子查询加在一起来获得。然后,您只需要第二次加入users
表(这次是针对上一篇文章)以获取所需的用户名:
SELECT topic.id
, topic.title
, topic.date
, topic.user_id
, topic_user.username
, t.count_posts
, lastpost.id
, lastpost.date
, lastpost_user.username
, IFNULL(lastpost.date, topic.date) AS pts
FROM topics topic
LEFT JOIN users topic_user ON topic_user.id = topic.user_id
LEFT JOIN (
(
SELECT topics_id
, COUNT(*) AS count_posts
, MAX(date) AS date
FROM posts
GROUP BY topics_id
) t JOIN posts lastpost USING (topics_id, date)
LEFT JOIN users lastpost_user ON lastpost_user.id = lastpost.user_id
) ON lastpost.topics_id = topic.id
ORDER BY pts DESC
LIMIT 10
请注意,我还要lastpost
而不是date
来识别id
,因为合成键不应该用于确定自然属性;但是,这假设date
实际上是一个时间戳。