TSQL левое соединение и только последняя строка справа
Я пишу sql-запрос, чтобы получить сообщение и только последний комментарий этого сообщения (если существует).
Но я не могу найти способ ограничить только 1 строку для правого столбца в левом соединении.
Вот пример этого запроса.
SELECT post.id, post.title,comment.id,comment.message
from post
left outer join comment
on post.id=comment.post_id
Если post имеет 3 комментария, я получаю 3 строки с этим сообщением, но хочу только 1 строку с последним комментарием (упорядоченным по дате).
Может кто-нибудь помочь мне с этим запросом?
Ответы
Ответ 1
SELECT post.id, post.title, comment.id, comment.message
FROM post
OUTER APPLY
(
SELECT TOP 1 *
FROM comment с
WHERE c.post_id = post.id
ORDER BY
date DESC
) comment
или
SELECT *
FROM (
SELECT post.id, post.title, comment.id, comment.message,
ROW_NUMBER() OVER (PARTITION BY post.id ORDER BY comment.date DESC) AS rn
FROM post
LEFT JOIN
comment
ON comment.post_id = post.id
) q
WHERE rn = 1
Первый более эффективен для нескольких должностей с множеством комментариев в каждом; последний более эффективен для многих сообщений с несколькими комментариями в каждом.
Ответ 2
подзапросов:
SELECT p.id, p.title, c.id, c.message
FROM post p
LEFT join comment c
ON c.post_id = p.id AND c.id =
(SELECT MAX(c.id) FROM comment c2 WHERE c2.post_id = p.id)
Ответ 3
Вам нужно присоединиться к подзапросу, который возвращает последний комментарий к сообщению. Например:
select post.id, post.title. lastpostid, lastcommentmessage
from post
inner join
(
select post.id as lastpostid, max(comment.id) as lastcommentmessage
from post
inner join comment on commment.post_id = post.id
group by post.id
) lastcomment
on lastpostid = post.id
Ответ 4
Пара вариантов....
Один из способов - выполнить JOIN:
SELECT TOP 1 comment.message FROM comment ORDER BY comment.id DESC
(обратите внимание, что я предполагаю, что comment.id - это поле Identity)
Ответ 5
какая версия SQL Server? Если у вас есть функция Row_Number(), вы можете сортировать свои комментарии тем, что для вас означает "первым", а затем просто добавить предложение "where RN = 1". У вас нет удобного примера или правильного синтаксиса с моей головы, но у вас есть тонны запросов, которые делают именно это. Другие сообщения - это всего лишь 1000 способов, которыми вы могли бы это сделать.
Я бы сказал, профиль и посмотрим, какой из них лучше всего подходит для вас.
Ответ 6
Вы не указали название своего поля даты, поэтому я заполнил [DateCreated]
. Это по существу то же самое, что и сообщение AGoodDisplayName выше, но с использованием поля даты вместо того, чтобы полагаться на упорядочение столбцов идентификатора.
SELECT post.id, post.title, comment.id, comment.message
FROM post p
LEFT OUTER JOIN comment
ON comment.id = (
SELECT TOP 1 id
FROM comment
WHERE p.id = post_id
ORDER BY [DateCreated] ASC
)