Нужна помощь с Join

0

Итак, я пытаюсь создать простой форум. Это будет список тем в порядке убывания на дату либо темы (если нет ответов), либо последнего ответа. Здесь структура БД:

Темы
id, subject, date, poster

сообщений
id, topic_id, message, date, poster

Сам форум будет состоять из таблицы HTML со следующими заголовками:
Topic | Last Post | Replies

Как будет выглядеть запрос или запросы для создания такой структуры? Я думал, что это будет связано с крестом, но не уверен... Спасибо заранее.

Теги:

3 ответа

1

Конечно, вы можете сделать запрос для этого, но я советую вам создать в темах "ответы" и "последнее сообщение" темы, а затем обновить их на каждом новом посту. Это может действительно улучшить скорость вашей базы данных, а не сейчас, но время, когда у вас будет тысячи тем.

  • 0
    Да, вы, вероятно, правы. Спасибо!
  • 0
    денормализация до того, как тщательные тесты покажут вам, что вам нужно это сделать, является примером преждевременной оптимизации.
0

Сам форум будет состоять из Таблица HTML со следующими заголовками:
Topic | Last Post | Replies

Если "Последнее сообщение" означает дату, это просто.

SELECT
  t.id,
  t.subject,
  MAX(p.date) AS last_post,
  COUNT(p.id) AS count_replies
FROM 
  Topics t
  INNER JOIN Posts p ON p.topic_id = t.id
GROUP BY
  t.id,
  t.subject

Если вам нужно отображать другие предметы вместе с последней датой публикации, например, ее id или poster, она становится немного сложнее.

SELECT
  t.id,
  t.subject,
  aggregated.reply_count,
  aggregated.distinct_posters,
  last_post.id,
  last_post.date,
  last_post.poster
FROM 
  Topics t
  INNER JOIN (
    SELECT   topic_id,
             MAX(p.date) AS last_date,
             COUNT(p.id) AS reply_count,
             COUNT(DISTINCT poster) AS distinct_posters
    FROM     Posts
    GROUP BY topic_id
  ) AS aggregated ON aggregated.topic_id = t.id
  INNER JOIN Posts AS last_post ON p.date = aggregated.last_date

В качестве примера я добавил количество отдельных плакатов для темы, чтобы показать вам, где этот подход может быть расширен.

Запрос основан на предположении, что никакие две должности в одной теме не могут иметь одну и ту же дату. Если вы ожидаете, что это произойдет, запрос должен быть изменен для его учетной записи.

0
SELECT *
FROM 
    `Topics`, 
    (
        SELECT *, COUNT(*) AS `replies`
        FROM `Posts`
        GROUP BY `Posts`.`topic_id`
        ORDER BY `Posts`.`date` DESC
    ) AS `TopicPosts`
WHERE `Topics`.`id` = `TopicPosts`.`topic_id` 
ORDER BY `Posts`.`date` DESC

Это "должно" работать или почти работать в случае, если это не так, но я согласен с другим плакатом, вероятно, лучше хранить эти данные в таблице тем по разным причинам, даже если это дублирование данных.

  • 0
    С верхней части моей головы...
  • 0
    Спасибо. Я думаю, что сделаю так, как сказал Thinker, но я сохраню этот код.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню