0

I'm trying to make a simple discussion board and as a result I need topics titles with their authors and authors of topics last posts.

So far I have this

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

I got here 10 latest topics titles, their authors usernames and IDs, number of messages in each topic, last ID and date of post in each topic, and everything sorted by activity... basically everything. All I need is authors username of those last posts. I guess I have to make one left join with subquery but I'm kinda stuck. Can someone help me?

4

1 回答 1

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

请注意,我也在识别lastpostbydate而不是id合成键不应该真正用于确定自然属性;但是,这假设这date实际上是一个时间戳。

于 2014-07-27T21:12:04.353 回答