Получить последнюю строку из другой таблицы в MySQL - PullRequest
0 голосов
/ 22 января 2009

Допустим, у меня есть две таблицы, новости и комментарии.

news (
  id,
  subject,
  body,
  posted
)

comments (
  id,
  parent,  // points to news.id
  message,
  name,
  posted
)

Я хотел бы создать один запрос, в котором будут собраны последние x # новостей, а также имя и дата публикации для последних комментариев для каждого сообщения.

Скорость имеет значение с точки зрения выбора ВСЕХ комментариев в подзапросе, не вариант.

Ответы [ 7 ]

3 голосов
/ 22 января 2009

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

SELECT news.*, comments.name, comments.posted, (SELECT count(id) FROM comments WHERE comments.parent = news.id) AS numComments
FROM news
LEFT JOIN comments
ON news.id = comments.parent
AND comments.id = (SELECT max(id) FROM comments WHERE parent = news.id) 
1 голос
/ 22 января 2009

Мое решение похоже на J , но я думаю, что он добавил одну ненужную строку:

SELECT news.*, comments.name, comments.posted FROM news INNER JOIN comments ON news.id = comments.parent WHERE comments.id = (SELECT max(id) FROM comments WHERE parent = news.id )

Не уверен в скорости на очень большом столе, хотя.

1 голос
/ 22 января 2009
SELECT news.subject, news.body, comments.name, comments.posted
FROM news
INNER JOIN comments ON
(comments.parent = news.id)
WHERE comments.parent = news.id
AND comments.id = (SELECT MAX(id)
FROM comments
WHERE parent = news.id)
ORDER BY news.id

Получает все новости вместе с соответствующим комментарием с наибольшим значением id, которое в теории должно быть самым последним.

1 голос
/ 22 января 2009

Предполагается, что опубликованная является уникальной меткой времени, в противном случае выберите уникальный номер

select c.id, c.parent, c.message, c.name, c.posted

  c.message, c.name, 

  c.posted -- same as comment_latest.recent

from comments c
join
(
    select parent, max(posted) as recent
    from comments
    group by parent
) as comment_latest
on c.parent = comment_latest.parent
and c.posted = comment_latest.recent

Завершено (отображает информацию о новостях):

select 

  n.id as news_id, n.subject, n.body, n.posted as news_posted_date

  c.id as comment_id, 
  c.message, c.name as commenter_name, c.posted as comment_posted_date

from comments c
join
(
    select r.parent, max(r.posted) as recent
    from comments r
    join 
    (
       select id from news order by id desc limit $last_x_news
    ) news l
    on r.parent = l.id
    group by r.parent
) as comment_latest
on c.parent = comment_latest.parent
and c.posted = comment_latest.recent

join news n on c.parent = n.id


Примечание:

Приведенный выше код не является подзапросом, это запрос на получение таблицы. Это быстрее, чем подзапрос. Это подзапрос (медленно):

select 
  id,
  subject,
  body,
  posted as news_posted_date,
  (select id from comments where parent = news.id order by posted desc limit 1) as comment_id,
  (select message from comments where parent = news.id order by posted desc limit 1) as message,
  (select name from comments where parent = news.id order by posted desc limit 1) as name,
  (select posted from comments where parent = news.id order by posted desc limit 1) as comment_posted_date,
from news
1 голос
/ 22 января 2009

Если скорость так важна, почему бы не создать таблицу Recent_comment, которая содержит идентификатор и идентификатор родителя только самых последних комментариев? Каждый раз, когда комментарий публикуется в новостном сообщении, заменяйте его самым последним идентификатором комментария. Создайте индекс в столбце идентификатора новостей новой таблицы, и ваши объединения будут быстрыми.

Вы будете торговать скоростью записи для скорости чтения, но не для всего лота.

0 голосов
/ 01 октября 2009

Я думаю, что решение @Jan является лучшим. Т.е. создайте «View» и соедините его с помощью оператора SQL.

Это определенно сократит время на извлечение данных. Я проверил это, и он работает на 100%.

0 голосов
/ 22 января 2009

Учитывая ограничения, выявленные в комментариях к моему другому ответу, у меня есть новая идея, которая может иметь или не иметь никакого смысла на практике.

Создайте представление (или функцию, если это более уместно) со следующим определением, называемым Recent_comments:

SELECT MAX(id), parent
FROM comments
GROUP BY parent

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

С помощью этого запроса вам нужно получить ответ, например,

SELECT news.*, comments.*
FROM news
INNER JOIN recent_comments
ON news.id = recent_comments.parent
INNER JOIN comments
ON comments.id = recent_comments.id

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...