web-dev-qa-db-ja.com

TSQLは左から結合し、右から最後の行のみ

投稿とこの投稿の最後のコメント(存在する場合)のみを取得する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行だけ必要です(日付順)。

誰かがこのクエリを手伝ってくれる?

32
barbarian
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

前者は、それぞれに多数のコメントがある少数の投稿に対してより効率的です。後者は、それぞれにコメントが少ない多くの投稿に対してより効率的です。

52
Quassnoi

サブクエリ:

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

投稿の最後のコメントを返すサブクエリに参加する必要があります。例えば:

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
3
Paul Williams

いくつかのオプション...

1つの方法は、次のようにJOINを実行することです。

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

(comment.idはIDフィールドであると想定しています)

1
Ian Jacobs

sQL ServerのバージョンRow_Number()関数を使用できる場合は、「最初」の意味でコメントをソートしてから、「where RN = 1」句を追加するだけです。頭の上の便利な例や正しい構文はありませんが、これを正確に実行するクエリはたくさんあります。他の投稿はすべて、1,000通りの方法で作成できます。

私はそれをプロファイリングして、どれがあなたにとって最もパフォーマンスが良いかを見ます。

日付フィールドの具体的な名前は言わなかったので、[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
)
0
Andy Raddatz