TSQL LEFT join et seulement la dernière ligne de droite

J'écris une requête sql pour obtenir le post et seulement Le Dernier commentaire de ce post(s'il existe). Mais je ne peux pas trouver un moyen de limiter seulement 1 ligne pour la colonne de droite dans LEFT join.

Voici un exemple de cette requête.

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

Si le post a 3 commentaires, je reçois 3 lignes avec ce post, mais je ne veux que 1 Ligne Avec Le Dernier commentaire (ordonné par date).

Quelqu'un Peut-il m'aider avec cette question?

31
demandé sur barbarian 2010-02-17 17:44:49

6 réponses

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

Ou

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

Le premier est plus efficace pour quelques messages avec beaucoup de commentaires dans chacun; le second est plus efficace pour de nombreux messages avec peu de commentaires dans chacun.

51
répondu Quassnoi 2015-01-06 17:32:28

Sous-Requête:

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
répondu AGoodDisplayName 2013-09-13 16:00:01

Vous voulez vous joindre à une sous-requête qui renvoie Le Dernier commentaire pour le post. Par exemple:

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
répondu Paul Williams 2010-02-17 14:49:26

Quelques options....

Une façon est de faire la jointure sur:

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

(notez que je suppose que comment.id est un champ D'identité)

1
répondu Ian Jacobs 2010-02-17 14:50:37

Quelle version de SQL Server? Si vous avez la fonction Row_Number() disponible, vous pouvez trier vos commentaires par ce que" first "signifie pour vous, puis ajoutez simplement une clause" where RN=1". Je n'ai pas un exemple pratique ou la bonne syntaxe du haut de ma tête, mais j'ai des tonnes de requêtes qui font exactement cela. D'autres messages sont tous dans les 1000 de façons dont vous pourriez le faire.

Je dirais profil et voir lequel fonctionne le mieux pour vous.

1
répondu No Refunds No Returns 2010-02-17 14:54:24

Vous n'avez pas dit le nom spécifique de votre champ de date, alors j'ai rempli avec [DateCreated]. Ceci est essentiellement le même que le post d'AGoodDisplayName ci-dessus, mais en utilisant le champ date au lieu de s'appuyer sur L'ordre de la colonne 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
répondu Andy Raddatz 2016-01-12 20:37:55