来自几个表的mysql数据

时间:2012-07-10 19:39:03

标签: mysql

我有一个尴尬的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

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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