我有一个尴尬的mySQL查询,由于数据库结构不佳(我多年前制作),我正在努力:/
我有3个表,forum_list
,forum_topics
和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
答案 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