#mysql #sql #join #subquery
#mysql #sql #Присоединиться #подзапрос
Вопрос:
У меня довольно простая система форумов. В трех основных таблицах, Topic, Comment и User, есть все обычные поля, которые вы можете себе представить, такие как автоинкрементные первичные ключи и внешние ключи друг к другу, поэтому я не думаю, что мне нужно излагать все это в мельчайших подробностях
Что я пытаюсь сделать, так это получить список самых последних опубликованных в темах. В представлении списка должны отображаться заголовок темы, текст первоначального комментария / публикации и имя автора, но список должен быть упорядочен по темам, которые были недавно опубликованы в первой.
Я не очень хорош в MySQL, кроме самых простых запросов. Очевидно, я мог бы разбить его на несколько запросов, но я хочу, чтобы это было в одном запросе для повышения производительности.
Вот что я придумал первым, но в ней темы упорядочены в соответствии со временем первого сообщения.
SELECT topic.id as topic_id, topic.title as topic_title, topic.datePosted as datePosted, topic.views as views, topic.numComments as numComments,
comment.ID as commentID, comment.body as body,
user.ID as userID, user.firstName, user.lastName, user.title as user_title, user.city, user.state, user.thumbnail
FROM comment INNER JOIN topic ON comment.topicID = topic.id
INNER JOIN user ON comment.userID = user.id
WHERE comment.id
IN (
SELECT min( comment.id )
FROM COMMENT INNER JOIN topic ON comment.topicID = topic.id
GROUP BY topic.id
)
ORDER BY commentID desc';
Комментарии:
1. Я смотрю на это сейчас. Первое, что бросается в глаза, это то, что datePosted должно быть полем в таблице комментариев, а не в таблице тем, верно? Я предполагаю, что вы хотите, чтобы для каждого комментария была установлена временная метка, а не только временная метка последнего комментария?
2. @burk Я думаю, @King Skuppus прав, что вы хотите опубликовать публикацию с самым последним комментарием к ней.
3. На самом деле у меня было поле datePosted как для таблиц комментариев, так и для таблиц тем. Я понял, что дату для темы можно определить, найдя самый ранний комментарий, но я пытаюсь сохранить информацию, а не постоянно ее вычислять. Я также предполагаю, что у меня могло бы быть другое поле для каждой темы, которое просто сохраняет временную метку самого последнего сообщения, и тогда у меня не возникло бы этого вопроса. Но мне любопытно, как это сделать таким образом.
Ответ №1:
Хорошо, вот мой первый ответ на то, что, я думаю, вы просите, список самых последних опубликованных комментариев в каждой теме. Дайте мне знать, если это не то, что вы ищете:
SELECT
t.title,
t.views,
t.numComments,
c.id,
c.datePosted,
c.body,
u.firstName,
u.lastName
FROM
topic AS t
INNER JOIN
( SELECT
c_inner.topicId,
MAX(c_inner.datePosted) AS latestPosted
FROM
comment AS c_inner
GROUP BY
c_inner.topicId ) AS cmax
ON t.id = cmax.topicId
INNER JOIN comment AS c
ON c.topicId = cmax.topicId AND c.datePosted = cmax.latestPosted
INNER JOIN user AS u
ON c.userId = u.id
ORDER BY c.datePosted DESC;
Если я неправильно понял, что вы ищете, не могли бы вы опубликовать пример ваших желаемых результатов?
Комментарии:
1. Последним опубликованным результатом действительно была дата / время последнего сообщения, поэтому я добавил
ORDER BY cmax.latestPosted DESC
в самый конец запроса, чтобы темы отображались в правильном порядке. Однако, возвращаемое тело комментария, похоже, не соответствует телу исходного сообщения темы. Я не решаюсь сказать, что это случайно, но я не уверен, что определяет, какой комментарий будет возвращен для каждой темы.2. Кроме того, я прошу прощения, если мне было неясно, что я искал. Я пытаюсь получить «сводный обзор» всех тем. Для каждой темы был бы набор результатов. В этом наборе результатов содержится название темы, начальный комментарий и информация об авторе. Эти результаты должны быть упорядочены по недавним действиям в теме. Таким образом, тема с самым последним комментарием (любым комментарием) появится первой.
3. Вы правы, я извлекал строки из неагрегированных данных. Я выполнил еще одно самостоятельное объединение, чтобы учесть это, и исправил ответ выше. Проанализируйте это и дайте мне знать, как это работает.
4. Это почти готово. Он возвращает тело самого последнего опубликованного комментария вместо тела исходного комментария. Спасибо за вашу помощь на данный момент.
5. О, я думал, это то, что вы хотели. Хм, оригинальный комментарий, а? Позвольте мне обдумать это еще несколько минут.