Вопрос

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

форум_тема

идентификатор, имя, адрес электронной почты, тело, дата

forum_reply

идентификатор, адрес электронной почты, тело, дата, идентификатор темы

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

Тема, Последнее изменение, # ответов

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

Это было полезно?

Решение

Во-первых, мне кажется, что никто на самом деле не отвечает на ваш вопрос, а именно:

Как будет выглядеть запрос или запросы для создания такой структуры?

с требуемой структурой

Тема, LastModified, # Ответов.

SQL для создания таблицы результатов с этой структурой, учитывая предоставленные вами структуры таблиц, будет следующим:

SELECT t.Id, t.Name AS Topic, 
       MAX(r.Date) AS LastModified, 
       COUNT(*) AS NumReplies
FROM Forum_Topic t
LEFT OUTER JOIN Forum_Reply r ON t.id = r.topic_id
GROUP BY t.Id, t.Name

(извините, это тестируется только на SQL Server, так как на данный момент у меня нет доступа к MySql)

Кроме того, ваша структура ЯВЛЯЕТСЯ уже нормализовалось.Предложения об обратном заключаются в предположениях о том, что вы хотите сделать, например, предполагая, что вы заинтересованы в отслеживании имен пользователей в добавление на адреса электронной почты.Это вполне разумно, но тем не менее является предположением.С точки зрения нормализации нет ничего плохого в использовании адреса электронной почты в качестве уникального идентификатора пользователя.

Теперь, если вам нужны общие рекомендации по настройке базы данных, мы можем дать вам МНОГО таких советов.Перед нормализацией я бы начал с того, что не использовал потенциальные ключевые слова в качестве имен объектов (например, не давал имена столбцам, такие как «Имя» и «Дата»).

Что касается комментария Мэтта о том, что значение равно NULL, когда нет ответов:использование функции COALESCE() исправит это.COALESCE() возвращает первый аргумент, отличный от NULL (или NULL, если все аргументы имеют значение NULL).Поэтому замените MAX(r.Date) на MAX(COALESCE(r.Date, t.Date)).

Другие советы

Примерно так:

select * from forum_topic
inner join forum_reply on forum_topic.id=topc_id

Однако не используйте select *

Это плохая практика :)

И мне не нравится, как ты избегаешь нормализации!Это означает, что я бы предпочел:

Пользователи

  • ID пользователя
  • Имя
  • Электронная почта

Потоки

  • Идентификатор потока
  • Предмет
  • Ответил
  • AskedByUserID
  • Дата

Ответы

  • Идентификатор ответа
  • Идентификатор потока
  • ID пользователя
  • Отвечать
  • Дата

Затем выберите тему следующим образом:

select ThreadID, Subject, Answered, AksedByUserID, Date from Threads

И выбрав все ответы, подобные этому

select Answer, Date, Name, Email from Threads
inner join Replies on Threads,ThreaID=Replies.ThreadID
inner join Users on AskedByUserID=UserID 
where Threads.ThreadID=xxx

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

Да, вы сможете получить его с помощью такого запроса:

SELECT 
  forum_topic.id, 
  forum_topic.name AS Topic,  
  MAX(forum_reply.date) AS Last_Modified, 
  count(*) AS  Replies
FROM forum_topic 
INNER JOIN forum_reply ON (forum_topic.id=forum_reply.topic_id)
GROUP BY forum_topic.id

«Группировка по» — это волшебство, которое дает нам одну строку для каждой темы с МАКС() и СЧИТАТЬ() функции, предоставляющие нам необходимые агрегированные данные.

(РЕДАКТИРОВАТЬ:Я пропустил тот факт, что тело первого сообщения было в таблице тем, поэтому сообщения без ответов не будут пропущены приведенным выше запросом.У Филипа правильная идея: он предлагает вам нормализовать ваши данные.После нормализации запрос, аналогичный приведенному выше, предоставит вам необходимые данные).

Под «нормализованным» вы подразумеваете, что столбец тела «forum_topic» должен быть удален, а фактическое тело темы должно быть первым ответом?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top