32 votes

TSQL jointure gauche et seulement la dernière ligne de droite

J'écris une requête sql pour obtenir le message et seulement le dernier commentaire de ce message (s'il existe). Mais je n'arrive pas à trouver un moyen de limiter seulement 1 ligne pour la colonne de droite dans la jointure gauche.

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 message a 3 commentaires, j'obtiens 3 lignes avec ce message, mais je veux seulement une ligne avec le dernier commentaire (ordonné par date).

Quelqu'un peut-il m'aider à répondre à cette question ?

52voto

Quassnoi Points 191041
SELECT  post.id, post.title, comment.id, comment.message
FROM    post
OUTER APPLY
        (
        SELECT  TOP 1 *
        FROM    comment с
        WHERE   comment.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

La première solution est plus efficace pour un petit nombre de messages avec beaucoup de commentaires dans chacun d'eux ; la seconde est plus efficace pour un grand nombre de messages avec peu de commentaires dans chacun d'eux.

15voto

AGoodDisplayName Points 1954

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)

3voto

Paul Williams Points 7390

Vous voulez joindre une sous-requête qui renvoie le dernier commentaire de l'article. 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

1voto

Ian Jacobs Points 4165

Quelques options....

Une façon de procéder est de faire le JOIN 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é)

1voto

Quelle version de SQL Server ? Si vous disposez de la fonction Row_Number(), vous pouvez trier vos commentaires selon ce que "premier" signifie pour vous, puis ajouter une clause "where RN=1". Je n'ai pas d'exemple pratique ni la bonne syntaxe en tête, mais j'ai des tonnes de requêtes qui font exactement cela. D'autres messages font état de milliers de façons de procéder.

Je dirais qu'il faut les profiler et voir lequel est le plus performant pour vous.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X