it-swarm.com.de

TSQL links und nur letzte Reihe von rechts

Ich schreibe eine SQL-Abfrage, um einen Beitrag zu erhalten, und nur den letzten Kommentar dieses Beitrags (falls vorhanden). Ich kann jedoch keine Möglichkeit finden, nur eine Zeile für die rechte Spalte in der linken Verknüpfung zu begrenzen.

Hier ist ein Beispiel für diese Abfrage.

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

Wenn der Beitrag 3 Kommentare enthält, bekomme ich 3 Zeilen mit diesem Beitrag, aber ich möchte nur 1 Zeile mit dem letzten Kommentar (geordnet nach Datum).

Kann mir jemand bei dieser Abfrage helfen?

31
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

oder

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

Ersteres ist für wenige Beiträge mit vielen Kommentaren effizienter; Letzteres ist für viele Beiträge mit wenigen Kommentaren effizienter.

51
Quassnoi

Unterabfrage:

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

Sie möchten sich einer Unterabfrage anschließen, die den letzten Kommentar für den Beitrag zurückgibt. Zum Beispiel:

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

Paar Optionen ....

Eine Möglichkeit ist das JOIN auf:

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

(Ich gehe davon aus, dass comment.id ein Identitätsfeld ist.)

1
Ian Jacobs

welche Version von SQL Server? Wenn Sie über die Funktion Row_Number () verfügen, können Sie Ihre Kommentare nach dem, was "erste" für Sie bedeutet, sortieren und dann eine Klausel "wobei RN = 1" hinzufügen. Habe kein praktisches Beispiel oder die richtige Syntax aus meinem Kopf, aber ich habe jede Menge Abfragen, die genau dies tun. Bei anderen Beiträgen gibt es alle 1.000 Möglichkeiten, dies zu erreichen.

Ich würde sagen, es profilieren und sehen, welche für Sie die beste Leistung bringt.

Sie haben den Namen Ihres Datumsfeldes nicht angegeben, also habe ich [DateCreated] eingegeben. Dies ist im Wesentlichen das Gleiche wie der Beitrag von AGoodDisplayName oben, verwendet jedoch das Datumsfeld, anstatt sich auf die Reihenfolge der ID-Spalten zu verlassen.

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