Итак, я пытаюсь построить простой форум. Это будет список тем в порядке убывания либо по дате темы (если нет ответов), либо по дате последнего ответа. Вот структура БД:
forum_topic
id, name, email, body, date
forum_reply
id, email, body, date, topic_id
Сам форум будет состоять из HTML-таблицы со следующими заголовками:
Topic, Last Modified, # Replies
Как бы выглядел запрос или запросы для создания такой структуры? Я думал, что это будет связано с перекрестным соединением, но не уверен ... Заранее спасибо.






Примерно так:
select * from forum_topic
inner join forum_reply on forum_topic.id=topc_id
Однако не используйте select *.
Это плохая практика :)
И мне не нравится, как вы избегаете нормализации! Это означает, что я бы предпочел:
Пользователи
Потоки
Ответы
Затем выберите тему следующим образом:
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
Это было написано с моей головы, но вам, возможно, также потребуется добавить некоторую группу.
Кажется, действительно происходит резкое голосование против. Я бы предположил, что в вашем случае это потому, что ваш запрос фактически не возвращает требуемые данные
Понятия не имею, почему вам отказали. К вашему сведению, столбцы были названы так для простоты объяснения :-)
То, что я предлагаю, - это просто пример того, как будет представлен «лучший» форум, и пример того, как использовать объединения, отрицательное голосование просто превосходно, когда я пытаюсь предоставить несколько хороших примеров.
Я подумал, что вы хотите выбрать ветку форума, а не список всех веток, прошу прощения за недоразумение. Для этого вы должны использовать COUNT и использовать предложение GROUP BY.
Также мой ответ является более общим, чтобы показать упрощенную структуру, которая соответствует правилам нормализации.
Да, вы сможете получить его с помощью такого запроса:
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" должен быть удален, а фактическое тело темы должно быть первым ответом?
Вы можете прочитать об этом здесь: devshed.com/c/a/MySQL/An-Introduction-to-Database-Normalizat ion
Нормализация в основном означает не повторяться, когда в этом нет необходимости. Например, у вас есть «Электронная почта» более чем в одном месте, я бы предпочел использовать для этого User-table.
Верно, это действительно компромисс. Дисковое пространство против процессорного времени. Объединение может быть дорогостоящим - нормализация - не всегда главное. В этом случае мне нужно, чтобы сама тема содержала поле описания. Что нужно сделать, чтобы изменить ваш запрос (или запрос Пола), чтобы отображать темы, даже без ответов?
Не очень много. Вы просто делаете:; выберите * из потоков внутреннего соединения Пользователи в потоках. AskedByUserID = UserID; который присоединится к Usertable, предоставляя вам информацию о пользователях и теме. Однако с ответами вам тоже нужно присоединиться. Дважды я бы сказал, хотите ли вы также запрашивать информацию о пользователе.
Во-первых, мне кажется, что noboody действительно отвечает на ваш вопрос:
What would the query or queries look like to produce such a structure?
с запрошенной структурой
Тема, 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)).
Это на 99%. Теперь появляются все темы. Единственная проблема сейчас в том, что LastModified = NULL, когда в теме нет ответов. Любые идеи?
На самом деле он не следует нормализации, если у вас есть ПК и электронная почта, и оба повторяются. Тогда у вас будет дублирование. Но это аргумент, поэтому давайте не будем об этом говорить, просто хотел указать на некоторые важные моменты и помочь в достижении цели :)
Роб, ты мужчина. Прекрасно работает. Спасибо всем за помощь!
Просто небольшой совет - это будет болезненно продлевать, если вы позже захотите добавить правильную систему входа в систему и / или структуру ответов с цепочкой.