0

我有一个尴尬的 mySQL 查询要进行,并且由于数据库结构不佳(我几年前就做到了)而苦苦挣扎:/

我有 3 张桌子forum_listforum_topicsforum_replies。我正在通过 forum_list 表循环,显示名称,并且我想获取每个帖子中最后一篇文章的日期和 author_id。

问题是,最后一个帖子可能是 中的回复forum_replies,也可能是主题forum_topics

我需要一个子查询还是什么?


桌子forum_list

id     name    
1      General Chat

桌子forum_topics

id    forum    author    date      
1     1        John      2012-12-12 12:12:12

桌子forum_replies

id    forum    topic    author    date
1     1        1        John      2012-12-12 12:12:12

更新

SELECT     forum_list.id
,          GREATEST(forum_topics.date, forum_replies.date) date
,          CASE GREATEST(forum_topics.date, forum_replies.date)
           WHEN forum_topics.date THEN MAX(forum_topics.author)
           WHEN forum_replies.date THEN MAX(forum_replies.author)
       END author
FROM       forum_list
LEFT JOIN  (
       SELECT   forum_topics.id
       ,        max(forum_topics.date) date
       FROM     forum_topics
       GROUP BY forum_topics.forum
       )        forum_topics_max
ON         forum_list.id = forum_topics_max.id
LEFT JOIN  forum_topics
ON         forum_topics_max.id = forum_topics.id
AND        forum_topics_max.date     = forum_topics.date
LEFT JOIN  (
       SELECT   forum_replies.id
       ,        max(forum_replies.date) date
       FROM     forum_replies
       GROUP BY forum_replies.topic
       )        forum_replies_max
ON         forum_list.id = forum_replies_max.id
LEFT JOIN  forum_replies
ON         forum_replies_max.id = forum_replies.id
AND        forum_replies_max.date     = forum_replies.date
GROUP BY   forum_list.id
4

2 回答 2

0

这应该得到答案,但它远非快速。

SELECT id, name, replies_1 .author, replies_1 .date
FROM forum_list
LEFT JOIN
(
    (SELECT forum, author, date FROM forum_topics)
    UNION
    (SELECT forum, author, date FROM forum_replies)
) AS replies_1 ON (replies_1.forum = forum_list.id)
LEFT JOIN
(
    (SELECT forum, author, date FROM forum_topics)
    UNION
    (SELECT forum, author, date FROM forum_replies)
) AS replies_2 ON (replies_2.forum = forum_list.id AND replies_2.date > replies_1.date)
WHERE replies_2.forum IS NULL;
于 2012-07-10T20:08:14.843 回答
0

这是一种方法:

SELECT     forum_lists.forum_id
,          GREATEST(forum_topics.date, forum_replies.date) date
,          CASE GREATEST(forum_topics.date, forum_replies.date)
               WHEN forum_topics.date THEN MAX(forum_topics.author)
               WHEN forum_replies.date THEN MAX(forum_replies.author)
           END author
FROM       forum_lists
LEFT JOIN  (
           SELECT   forum_topics.forum_id
           ,        max(forum_topics.date) date
           FROM     forum_topics
           GROUP BY forum_lists.forum_id
           )        forum_topics_max
ON         forum_lists.forum_id = forum_topics_max.forum_id
LEFT JOIN  forum_topics
ON         forum_topics_max.forum_id = forum_topics.forum_id
AND        forum_topics_max.date     = forum_topics.date
LEFT JOIN  (
           SELECT   forum_replies.forum_id
           ,        max(forum_replies.date) date
           FROM     forum_replies
           GROUP BY forum_replies.forum_id
           )        forum_replies_max
ON         forum_lists.forum_id = forum_replies_max.forum_id
LEFT JOIN  forum_replies
ON         forum_replies_max.forum_id = forum_replies.forum_id
AND        forum_replies_max.date     = forum_replies.date
GROUP BY   forum_lists.forum_id

它看起来很复杂,但假设 forum_lists 不是太大,我认为这个解决方案会比 Kaii 的更快,尤其是随着 forum_replies 和 forum_topics 越来越大。

这是使用相关子查询的替代解决方案。它们通常比上面的解决方案慢,但如果 forum_lists 非常大(不太可能),那么它可能会更快:

SELECT     forum_lists.forum_id
,          GREATEST(forum_topics.date, forum_replies.date) date
,          CASE GREATEST(forum_topics.date, forum_replies.date)
               WHEN forum_topics.date THEN MAX(forum_topics.author)
               WHEN forum_replies.date THEN MAX(forum_replies.author)
           END author
FROM       forum_lists
LEFT JOIN  forum_topics
ON         forum_lists.forum_id = forum_topics.forum_id
AND        forum_topics.date = (
               SELECT MAX(date)
               FROM   forum_topics forum_topics_max
               WHERE  forum_topics_max.forum_id = forum_topics.forum_id
           )
LEFT JOIN  forum_replies
ON         forum_lists.forum_id = forum_replies.forum_id
AND        forum_replies.date = (
               SELECT MAX(date)
               FROM   forum_replies forum_replies_max
               WHERE  forum_replies_max.forum_id = forum_replies.forum_id
           )
GROUP BY   forum_lists.forum_id
于 2012-07-10T20:11:41.440 回答