Вопрос SQL-запроса:У X есть много Y.Получите все X и получите только самые новые Y за X
Вопрос
Предположим, у нас есть две таблицы.Публикуйте и комментируйте.Пост имеет много комментариев.Представьте, что они несколько заполнены, чтобы количество комментариев к посту было разным.Мне нужен запрос, который будет захватывать все сообщения, но только самые новые комментарии к каждому сообщению.
Меня направили на объединения и подзапросы, но я не могу в этом разобраться.
Пример вывода:
Сообщение1:Комментарий 4 (самый новый к сообщению 1)
Сообщение2:Комментарий 2 (самый новый для сообщения 2)
Сообщение3:Комментарий 10 (самый новый к сообщению 3)
и т. д...
Любая помощь будет принята с благодарностью.Спасибо.
Решение
В этом ответе предполагается, что у вас есть уникальный идентификатор для каждого комментария и что его число увеличивается.То есть более поздние публикации имеют более высокие номера, чем более ранние.Не обязательно быть последовательным, просто должно соответствовать порядку ввода.
Сначала выполните запрос, который извлекает максимальный идентификатор комментария, сгруппированный по идентификатору сообщения.
Что-то вроде этого:
SELECT MAX(ID) MaxCommentID, PostID
FROM Comments
GROUP BY PostID
Это даст вам список идентификаторов сообщений и самый высокий (последний) идентификатор комментария для каждого из них.
Затем вы присоединяетесь к этому, чтобы извлечь остальные данные из комментариев для этих идентификаторов.
SELECT C1.*, C2.PostID
FROM Comments AS C1
INNER JOIN (
SELECT MAX(ID) MaxCommentID, PostID
FROM Comments
GROUP BY PostID
) AS C2 ON C1.CommentID = C2.MaxCommentID
Затем вы присоединяетесь к публикациям, чтобы получить информацию об этих публикациях.
SELECT C1.*, P.*
FROM Comments AS C1
INNER JOIN (
SELECT MAX(ID) MaxCommentID, PostID
FROM Comments
GROUP BY PostID
) AS C2 ON C1.CommentID = C2.MaxCommentID
INNER JOIN Posts AS P ON C2.PostID = P.ID
Альтернативный подход вообще не использует PostID внутреннего запроса.Во-первых, выберите максимальный идентификатор комментария для всех уникальных сообщений, но не важно, какое сообщение, мы знаем, что они уникальны.
SELECT MAX(ID) AS MaxCommentID
FROM Comments
GROUP BY PostID
Затем выполните предложение IN, чтобы получить остальные данные для этих комментариев:
SELECT C1.*
FROM Comments
WHERE C1.ID IN (
SELECT MAX(ID) AS MaxCommentID
FROM Comments
GROUP BY PostID
)
Тогда просто присоединяйтесь к публикациям:
SELECT C1.*, P.*
FROM Comments AS C1
INNER JOIN Posts AS P ON C1.PostID = P.ID
WHERE C1.ID IN (
SELECT MAX(ID) AS MaxCommentID
FROM Comments
GROUP BY PostID
)
Другие советы
Выберите самый новый комментарий из подзапроса
например
Select *
from Posts po
Inner Join
(
Select CommentThread, CommentDate, CommentBody, Post from comments a
inner join
(select commentthread, max(commentdate)
from comments b
group by commentthread)
on a.commentthread = b.commentthread
and a.commentdate = b.commentdate
) co
on po.Post = co.post
select *
from post
, comments
where post.post_id = comments.post_id
and comments.comments_id = (select max(z.comments_id) from comments z where z.post_id = post.post_id)
И если вы все еще используете старую версию MySQL, которая не знает подзапросов, вы можете использовать что-то вроде
SELECT p.id, c1.id FROM posts as p LEFT JOIN comments as c1 ON p.id = c1.postId LEFT JOIN comments as c2 ON c1.postId = c2.postId AND c1.id < c2.id WHERE isnull(c2.id) ORDER BY p.idВ любом случае проверьте свой запрос с помощью ОБЪЯСНЯТЬ для проблем с производительностью.