Проблема с вашим подзапросом, чтобы найти последний пост, состоит в том, что нет никаких причин для last_post_time, topic_title и т. Д. Принадлежать строке, которая имеет MAX (last_post_time).
Подумайте над этим запросом:
SELECT MAX(last_post_time), MIN(last_post_time), topic_title
FROM forum_topics
GROUP BY forum_id
Какой topic_title это возвращает? Тот из ряда с наибольшим временем публикации? Тот из ряда с наименьшим количеством сообщений? Это неоднозначно - MySQL может выбрать только один topic_title из группы произвольно. На практике он выбирает из строки, которая сначала физически хранится в группе, и это вне вашего контроля, в зависимости от реализации механизма хранения и т. Д.
Вот альтернативный дизайн, который находит строку forum_topics, для которой не существует другой строки forum_topics с большим значением last_post_time:
SELECT root.name AS root_name
, subcat.name AS subcat_name
, subcat.id AS subcat_id
, subcat.description AS subcat_description
, subcat.safe_url AS subcat_safe_url
, topics.*
FROM forum_category AS root
LEFT JOIN forum_category AS subcat ON subcat.parent_id = root.id
LEFT JOIN forum_topics AS topics ON topics.forum_id = subcat.id
LEFT JOIN forum_topics AS t2 ON t2.forum_id = subcat.id
AND t2.last_post_time > topics.last_post_time
WHERE root.parent_id = 0 AND t2.forum_id IS NULL
ORDER BY root_name, subcat_name