0

厄介な mySQL クエリを作成する必要があり、データベース構造が貧弱であるために苦労しています (何年も前に作成しました):/

forum_list、 、forum_topicsおよびの 3 つのテーブルがありforum_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

これを行う1つの方法は次のとおりです。

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 が大きすぎないと仮定すると、特に forum_replies と forum_topics が大きくなるにつれて、このソリューションは Kaii よりも高速になると思います。

相関サブクエリを使用した代替ソリューションを次に示します。それらは通常、上記のソリューションよりも遅くなりますが、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 に答える
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 に答える