2009-04-07 4 views
1

ich Probleme habe eine MySQL-Abfrage bildet, die folgende Aktion ausführt:MySQL Query ein „bump-System“ für ein Forum zu schaffen, ich bin machen

Wählen Sie alle threadIDs aus der Threads Tabelle Bestellung durch den Zeitstempel (in absteigender Reihenfolge) des letzten Posts (größter Zeitstempel) mit threadID gleich der threadID jedes threads. Also im Grunde möchte ich durch die Threads gehen und MySQL die Datenbank für Thread 0 überprüfen lassen. Es überprüft dann alle Beiträge, die threadID von 0 haben und sortiert thread0 basierend auf dem größten Zeitstempel der Beiträge innerhalb von thread0. Dann wiederholt es dies für thread1, thread2 usw. und sortiert sie entsprechend.

Ist das überhaupt möglich? Es wird der "Bump-System" -Effekt des Forums erzeugt, wo der zuletzt aktive Thread kontinuierlich an den Anfang der Liste gestoßen wird, bis der Thread ausstirbt, und dann nach unten fällt. Früher habe ich eine andere Implementierung verwendet, in der ich einen lastActivity-Zeitstempel in der Thread-Tabelle gespeichert und aktualisiert habe, als ein neuer Beitrag in den Thread gesendet wurde, aber diese Abfrage würde die Dinge viel effizienter machen.

Vielen Dank! Hier sind zwei Tabellen relevant: Threads und Posts. Die Posts haben ein threadID-Feld, in dem die ID des Threads gespeichert ist, zu dem es gehört, und es hat auch ein Timestamp-Feld. Threads hat eine Feld-Thread-ID, die der Thread-ID des Posts entspricht.

Antwort

2

Folgendes hat für mich in der Vergangenheit auf MySql funktioniert. Wenn Sie mehr Informationen zu jedem Thread in die Abfrage aufnehmen möchten, müssen Sie die Spalten SELECT und GROUP BY hinzufügen.

select thread.threadID, max(comments.modifiedOn) as threadUpdated 
    from thread inner join comments on thread.threadID = comments.threadID 
    group by 1 
    order by 2 desc; 

Diese Abfrage dient primäre Anforderung, die eine Liste der Themen ist mein letzter Kommentar bestellt. Es werden keine Threads ohne Kommentare zurückgegeben, so wie sie sind. Dazu müssten Sie den Join zu einem äußeren Join ändern.

2
SELECT * 
FROM threads t 
LEFT JOIN 
     posts p 
ON  p.id = 
     (
     SELECT p.id 
     FROM posts pi 
     WHERE pi.threadID = t.threadID 
     ORDER BY 
       pi.timestamp DESC 
     LIMIT 1 
     ) 

Mit einem Index auf posts (threadID, timestamp) wird diese Abfrage erheblich verbessern.

Beachten Sie, dass diese Abfrage im Gegensatz zu GROUP BY Lösungen auch alle Felder aus posts auswählt und funktioniert, selbst wenn Sie auf dem neuesten posts.timestamp Duplikate haben.

+0

Haben Sie das versucht? IIRC, MySQL unterstützt nicht die Verwendung von LIMIT in einer Unterabfrage. –

+0

Sicher habe ich. MySQL unterstützt LIMIT innerhalb einer IN-Unterabfrage nicht, es ist in Ordnung, wenn eine einfache Unterabfrage mit Gleichheitsbedingung verwendet wird. – Quassnoi

0
SELECT t.*, p1.`timestamp` 
FROM threads t 
    JOIN posts p1 ON (p1.threadid = t.id) 
    LEFT JOIN posts p2 ON (p2.threadid = t.id 
    AND p1.`timestamp` < p2.`timestamp`) 
WHERE p2.threadid IS NULL 
ORDER BY p1.`timestamp` DESC; 
+0

Dies filtert die Duplikate eines minimalen Zeitstempels in keinem aus, oder? – Quassnoi

+0

Guter Punkt. Wenn Sie möglicherweise doppelte Zeitstempel haben, müssen Sie einen Ausdruck in der Join-Bedingung hinzufügen, um den Primärschlüssel oder etwas Vergleichbares zu erhalten. –