2009-04-29 5 views
1

Angenommen, wir haben zwei Tabellen. Post und Kommentar. Post hat viele Kommentare. Stellen Sie sich vor, dass sie etwas gefüllt sind, so dass die Anzahl der Kommentare pro Post variiert. Ich möchte eine Abfrage, die alle Posts aber nur den neuesten Kommentar per Post packt.SQL-Abfrage Frage: X hat viele Y. Get alle X und bekomme nur die neueste Y pro X

Ich wurde auf Joins und Unterabfragen verwiesen, aber ich kann es nicht herausfinden.

Ausgabe:

Post1: comment4 (neueste für post1)

Post2: Comment2 (neueste für POST2)

Post3: Comment 10 (neueste für Post3)

etc ...

Jede Hilfe würde sehr geschätzt werden. Vielen Dank.

Antwort

3

Bei dieser Antwort wird davon ausgegangen, dass Sie für jeden Kommentar eine eindeutige ID haben und dass es sich um eine steigende Zahl handelt. Das heißt, spätere Posts haben höhere Nummern als frühere Posts. Muss nicht sequentiell sein, muss nur der Reihenfolge der Eingabe entsprechen.

Zuerst eine Abfrage, die die maximale Kommentar-ID extrahiert, gruppiert nach Post-ID.

Etwas wie folgt aus:

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

Dies wird Ihnen eine Liste der Post-ID ist, und die höchste (neuesten) Kommentar-ID für jeden.

Dann verbinden Sie sich damit, um den Rest der Daten aus den Kommentaren für diese IDs zu extrahieren.

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 

Dann werden Sie mit den Beiträgen beitreten, um die Informationen über diese Beiträge zu erhalten.

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 

Ein alternativer Ansatz, um die PostID der inneren Abfrage überhaupt nicht verwenden. Wählen Sie zuerst die maximale Kommentar-ID für alle eindeutigen Posts aus, aber egal, welchen Post wir kennen, sie sind einzigartig.

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

Dann eine IN-Klausel tun, um den Rest der Daten für diese Äusserungen zu bekommen:

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

dann einfach in den Beiträgen kommen:

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

den neuesten Kommentar Wählen Sie aus eine Unterabfrage

e.

g
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 
+0

Wenn ein Beitrag nicht unbedingt Kommentare haben, verwenden Sie den linken äußeren Join nicht den inneren Join zwischen den Beiträgen und Kommentaren – u07ch

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

Und wenn Sie noch mit einer alten MySQL-Version gesteckt werden sollen, die nicht von Unterabfragen nicht kennt Sie so etwas wie

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
So oder so verwenden kann, überprüfen Sie die Abfrage mit EXPLAIN für Performance-Probleme.