Question de requête SQL: X a plusieurs Y. Obtenez tous les X et obtenez uniquement le plus récent Y par X

StackOverflow https://stackoverflow.com/questions/804397

  •  03-07-2019
  •  | 
  •  

Question

Supposons que nous ayons deux tables. Publier et commenter. Le post a beaucoup de commentaires. Imaginez qu'ils soient quelque peu remplis, de sorte que le nombre de commentaires par publication varie. Je souhaite une requête qui saisira tous les articles, mais uniquement le dernier commentaire par article.

J'ai été dirigé vers les jointures et les sous-requêtes, mais je n'arrive pas à le comprendre.

Exemple de sortie:

Post1: Comment4 (le plus récent pour post1)

Post2: Comment2 (le plus récent pour post2)

Post3: Commentaire 10 (le plus récent pour post3)

etc ...

Toute aide serait grandement appréciée. Merci.

Était-ce utile?

La solution

Cette réponse suppose que vous avez un identifiant unique pour chaque commentaire et qu'il s'agit d'un nombre croissant. C'est-à-dire que les messages postérieurs ont des nombres plus élevés que les messages précédents Ne doit pas nécessairement être séquentiel, il doit simplement correspondre à l'ordre d'entrée.

Commencez par créer une requête qui extrait l'identifiant de commentaire maximal, groupé par identifiant de publication.

Quelque chose comme ça:

SELECT MAX(ID) MaxCommentID, PostID
FROM Comments
GROUP BY PostID

Ceci vous donnera une liste d'identifiants de publication et l'identifiant de commentaire le plus élevé (le plus récent) pour chacun d'entre eux.

Ensuite, vous vous associez à ceci pour extraire le reste des données des commentaires, pour ces identifiants.

SELECT C1.*, C2.PostID
FROM Comments AS C1
     INNER JOIN (
         SELECT MAX(ID) MaxCommentID, PostID
         FROM Comments
         GROUP BY PostID
     ) AS C2 ON C1.CommentID = C2.MaxCommentID

Ensuite, vous vous joignez aux publications pour obtenir des informations sur ces publications.

SELECT C1.*, P.*
FROM Comments AS C1
     INNER JOIN (
         SELECT MAX(ID) MaxCommentID, PostID
         FROM Comments
         GROUP BY PostID
     ) AS C2 ON C1.CommentID = C2.MaxCommentID
     INNER JOIN Posts AS P ON C2.PostID = P.ID

Une autre approche n’utilise pas du tout l’identifiant PostID de la requête interne. Tout d’abord, choisissez l’identifiant de commentaire maximal pour tous les articles uniques, mais ne vous souciez pas de quel article, nous savons qu'ils sont uniques.

SELECT MAX(ID) AS MaxCommentID
FROM Comments
GROUP BY PostID

Ensuite, faites une clause IN pour obtenir le reste des données pour ces commentaires:

SELECT C1.*
FROM Comments
WHERE C1.ID IN (
    SELECT MAX(ID) AS MaxCommentID
    FROM Comments
    GROUP BY PostID
)

Ensuite, rejoignez simplement les messages:

SELECT C1.*, P.*
FROM Comments AS C1
     INNER JOIN Posts AS P ON C1.PostID = P.ID
WHERE C1.ID IN (
    SELECT MAX(ID) AS MaxCommentID
    FROM Comments
    GROUP BY PostID
)

Autres conseils

Sélectionnez le commentaire le plus récent dans une sous-requête

exemple

Select * 
from Posts po
Inner Join
(
Select CommentThread, CommentDate, CommentBody, Post from comments a
inner join 
(select commentthread, max(commentdate)
from comments b
group by commentthread)
on a.commentthread = b.commentthread
and a.commentdate = b.commentdate
) co
on po.Post = co.post
 select *
   from post
      , comments
  where post.post_id = comments.post_id
    and comments.comments_id = (select max(z.comments_id) from comments z where z.post_id = post.post_id)

Et si vous êtes toujours bloqué avec une ancienne version de MySQL, qui ne connaît pas les sous-requêtes, vous pouvez utiliser quelque chose comme

SELECT
  p.id, c1.id
FROM
  posts as p
LEFT JOIN
  comments as c1
ON
  p.id = c1.postId
LEFT JOIN
  comments as c2
ON
  c1.postId = c2.postId
  AND c1.id < c2.id
WHERE
  isnull(c2.id)
ORDER BY
  p.id
Dans tous les cas, vérifiez votre requête avec EXPLAIN pour les problèmes de performances.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top