TSQL левое соединение и только последний ряд справа - PullRequest
31 голосов
/ 17 февраля 2010

Я пишу SQL-запрос, чтобы получить сообщение и только последний комментарий к этому сообщению (если существует).Но я не могу найти способ ограничить только 1 строку для правого столбца в левом соединении.

Вот пример этого запроса.

SELECT post.id, post.title,comment.id,comment.message
from post
left outer join comment
on post.id=comment.post_id

Если в посте 3 комментария, я получу 3строк с этим сообщением, но я хочу только 1 строку с последним комментарием (упорядочено по дате).

Может ли кто-нибудь помочь мне с этим запросом?

Ответы [ 6 ]

51 голосов
/ 17 февраля 2010
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

Первый вариант более эффективен для нескольких постов с большим количеством комментариев в каждом;последний более эффективен для многих постов с небольшим количеством комментариев в каждом.

14 голосов
/ 17 февраля 2010

подзапросы:

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 голосов
/ 17 февраля 2010

Вы хотите присоединиться к подзапросу, который возвращает последний комментарий к сообщению.Например:

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
1 голос
/ 17 февраля 2010

какая версия SQL Server? Если у вас есть доступная функция Row_Number (), вы можете отсортировать комментарии по любому значению «сначала», а затем просто добавить предложение «где RN = 1». У меня нет удобного примера или правильного синтаксиса, но у меня есть тонны запросов, которые делают именно это. Другие посты - это тысячи способов сделать это.

Я бы сказал, профилировать его и посмотреть, какой из них лучше для вас.

1 голос
/ 17 февраля 2010

Пара вариантов ....

Один из способов - присоединиться к:

SELECT TOP 1 comment.message FROM comment ORDER BY comment.id DESC

(обратите внимание, я предполагаю, что comment.id является полем Identity)

0 голосов
/ 12 января 2016

Вы не назвали конкретное название поля даты, поэтому я заполнил [DateCreated]. По сути, это то же самое, что и публикация AGoodDisplayName выше, но с использованием поля даты вместо того, чтобы полагаться на порядок столбцов ID.

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
)
...