Получить данные из двух таблиц в зависимости от данных из одной в одном запросе - PullRequest
0 голосов
/ 29 марта 2009

Я делаю простой форум, и в списке тем я хочу показать классическое "последнее сообщение (user) at (date)". Я использую только одну таблицу, чтобы содержать все сообщения на форуме, где сообщения с полем parentPost, не равным нулю, являются ответами в теме.

Это таблицы и необходимые поля, из которых мне нужны данные:

forumPosts
  • id : целое число, первичный ключ
  • title : строковое значение
  • дата : строковое значение
  • parentPost : целое число (Это поле = идентификатор исходного сообщения в теме. Если значение равно NULL, сообщение является "исходным сообщением в теме")
  • author : целое число, внешний ключ к таблице пользователей
  • countAnswers : целое число
  • lastPost : целое число, (Это поле = идентификатор последнего сообщения, на которое был дан ответ. Используется, только когда поле parentPost-field = NULL)
пользователи
  • ИД пользователя : целое число, первичный ключ
  • firstName : строковое значение
  • фамилия : строковое значение

На данный момент у меня есть этот запрос:

SELECT forumPosts.id, forumPosts.title, forumPosts.date, forumPosts.author, forumPosts.countAnswers, users.firstName, users.lastName 
FROM forumPosts 
INNER JOIN users ON forumPosts.author = users.userid 
WHERE forumPosts.parentPost IS NULL ORDER BY id DESC;

Возвращает все, что мне нужно (ID, заголовок, дата, автор и количество ответов), за исключением даты и автора последнего опубликованного ответа.

Кроме того, я хотел бы получить следующее:

Дата последнего сообщения в теме, то есть сообщение с наибольшим идентификатором и parentPost = forumPosts.id. Я также хотел бы получить firstName и lastName от пользователя, который разместил этот ответ.

Я уже давно дурачусь с разными объединениями и производными таблицами и тому подобным, но, похоже, я не могу понять это правильно. В идеале я хотел бы вернуть таблицу со следующими полями:

  • ID
  • название
  • дата
  • 1069 * ПгвЬЫат *
  • Фамилия
  • countAnswers
  • lastReplyDate
  • lastReplyFirstName
  • lastReplyLastName

Мне это кажется возможным, но я, очевидно, не могу этого сделать.

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

Раствор

SELECT        forumPosts.id, forumPosts.title, forumPosts.date, forumPosts.author, forumPosts.countAnswers, users.firstName, users.lastName, 
                     lastPost.date AS lastPostDate, lastUser.firstName AS lastPostFirstName, lastUser.lastName AS lastPostLastName
FROM            forumPosts AS lastPost INNER JOIN
                     users AS lastUser ON lastPost.author = lastUser.userid INNER JOIN
                     forumPosts INNER JOIN
                     users ON forumPosts.author = users.userid ON lastPost.id = forumPosts.lastPost
WHERE        (forumPosts.parentPost IS NULL)
ORDER BY forumPosts.id DESC

Это сработало. Очень типично, найти свой ответ через минуту после того, как я потратил много времени на написание поста здесь: - \

Ответы [ 2 ]

2 голосов
/ 29 марта 2009

Если «нить» является важной концепцией для вашей системы - и похоже, что это так - я бы смоделировал ее как отдельную сущность. Идентификация тем по сообщениям, у которых нет родителя, может вызвать у вас горе, когда вы только начинаете их обнаруживать.

За одну вещь, чтобы найти все темы:

SELECT ... FROM posts WHERE parent IS NULL

в зависимости от поставщика базы данных обычно не работает, потому что значения NULL обычно не индексируются.

Создайте таблицу потоков, и все эти проблемы исчезнут.

1 голос
/ 29 марта 2009
SELECT f.id, f.title, f.date, 
 u1.firstName, u1.lastName, f.countAnswers,
 r1.date AS lastReplyDate,
 u2.firstName AS lastReplyFirstName
 u2.lastName AS lastReplyLastName
FROM forumPosts f
 INNER JOIN users u1 ON (f.author = u1.userid)
 LEFT OUTER JOIN (forumPosts r1 INNER JOIN users u2 ON r1.author = u2.userid)
  ON (f.id = r1.parentPost)
 LEFT OUTER JOIN forumPosts r2 
  ON (f.id = r1.parentPost AND r1.id < r2.id)
WHERE f.parentPost IS NULL 
 AND r2.id IS NULL
ORDER BY f.id DESC;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...