Denkfehler bei Gruppierung und Sortierung

Tobias Menzel

Erfahrenes Mitglied
Hi Forum,

Ich möchte in einem Forum die 5 neusten Beiträge anzeigen lassen, dabei aber jeden Thread nur einmal in der Liste haben. Mein Ansatz war ein simple Sortierung nach Datum (absteigend) mit einer Gruppierung nach Thread-ID:
Code:
SELECT * FROM posting GROUP BY thread ORDER BY date DESC LIMIT 5
Die Ergebnisse der Forensuche sagen mir, dass die Sortierung nach der Gruppierung vorgenommen wird (siehe z.B. hier). Damit sollten nach meiner Logik die ausgegebenen Postings zumindest absteigend nach Datum sortiert sein - sind sie aber nicht. :suspekt:

Ich würde mich freuen, wenn mich jemand mit der Nase auf den Denkfehler stoßen würde.

Gruß
.
 
Also, wenn du GROUP BY verwendest, kannst du ja nichtmehr auf die einzelnen Daten der Einträge zurückgreifen, da du nach dem thread gruppierst.

Ich vermute mal nachdem wie ich das verstehe, dass du zudem nach dem Datum gruppieren musst.

Versuchs mal mit:

Code:
SELECT * FROM posting GROUP BY thread,date ORDER BY date DESC LIMIT 5
 
Du hast (auf diese Weise) keinen Einfluss darauf, welcher Datensatz der Gruppe im Ergebnis landet. Da die Gruppierung vor der Sortierung statt findet, ist letztere, bezogen auf den Thread, schon fast zufällig.

Abhilfe schafft der Ansatz, den Tom einmal gepostet hat oder auch ein Subquery in MySQL ab Version 4.1.

Ich versuche es mal an Deinem Problem:
Code:
SELECT 
  p1.posting,
  p1.thread,
  p1.`date`,
  p1.weitereFelder
FROM posting p1
LEFT JOIN posting p2
  ON p1.thread=p2.thread
    AND p1.`date` < p2.`date`
WHERE p2.thread IS NULL
ORDER BY date DESC 
LIMIT 5
Im WHERE-Teil solltest Du ein Feld aus der Tabelle nehmen, welches als NOT NULL definiert ist.

Achtung: date ist in MySQL ein Schlüsselwort und kann als Feldname zu Problemen führen.

Gruß hpvw
 
Hi,

EDIT: @hpvw: Den Beitrag habe ich auch gesehen - allerdings dachte ich, dass das in etwa der umgekehrte Fall wäre. "Sortierung nach Gruppierung" sagt für mein Verständnis aus, dass ich erst einen Eintrag pro Gruppe bekomme und dann werden diese Einträge nach dem Datum sortiert - scheint allerdings nicht so zu sein.

Danke erstmal: Ich teste das eben, und dann melde ich mich ggf. wieder (oder markiere das Thema als Erledigt).

Gruß
.
 
Zuletzt bearbeitet:
Nachtrag:

Danke, so komm ich klar:
Code:
	$query = 'SELECT 
 	p1.id,
  	p1.thread,
 	p1.user
	FROM posting p1
	LEFT JOIN posting p2
 		ON p1.thread=p2.thread
   		AND p1.date < p2.date
	WHERE p2.thread IS NULL
	ORDER BY p1.date DESC 
	LIMIT 5';
Was ich nicht ganz verstanden habe, ist, wie p2.thread null sein kann - aber ich denke, ich muss mich noch einmal etwas weiter durchs Handbuch lesen. ;)

Gruß

P.S.: Seltsamerweise habe ich mit "date" als Spaltennamen in mySQL (4.0.16) nie Probleme gehabt - bei anderen reservierten Wörtern bekomme ich allerdings regelmäßig eine Fehlermeldung.
.
 
Datic hat gesagt.:
Was ich nicht ganz verstanden habe, ist, wie p2.thread null sein kann - aber ich denke, ich muss mich noch einmal etwas weiter durchs Handbuch lesen. ;)
Das funktioniert durch den LEFT JOIN.

Dieser garantiert, dass jeder Datensatz aus der linken Tabelle (hier p1) im Ergebnis erscheint.

Sollte es keinen Datensatz in der rechten Tabelle (hier p2) geben, der der Bedingung hinter ON genügt, werden die Felder dieser Tabelle NULL gesetzt (egal ob sie als NULL oder NOT NULL definiert sind) und die Zeile in das Ergebnis aufgenommen.

Ist der Datensatz in p1 der Größte der Gruppe, kann es in p2 keinen Datensatz geben, der ein größeres Datum hat und zum gleichen thread gehört. Genau diese Datensätze willst Du haben, daher die Prüfung auf IS NULL.

Hierdurch sollte auch klar sein, warum das geprüfte Feld als NOT NULL definiert sein sollte, denn alle anderen Verknüpfungen durch den LEFT JOIN haben in dem Feld den Wert stehen, der auch in der Datenbank steht. Wenn dieser auch NULL annehmen kann, könntest Du auch Ergebnisse erhalten, die nicht das jeweils jüngste Posting im Thread sind.

Datic hat gesagt.:
"Sortierung nach Gruppierung" sagt für mein Verständnis aus, dass ich erst einen Eintrag pro Gruppe bekomme und dann werden diese Einträge nach dem Datum sortiert - scheint allerdings nicht so zu sein.
Doch, genau so ist es. Ein beliebiger Datensatz wird aus der Gruppe aufgenommen, die anderen "verfallen", dann wird sortiert.

Gruß hpvw
 
Oh,

na dann ist klar. ;) Danke für die verständliche Erklärung.

"thread" ist ein Fremdschlüssel und als NOT NULL definiert-

Gruß

P.S. @Gruppierung: Langsam dämmert mir mein Denkfehler: Ich habe nämlich hinterher die Thread-IDs genommen und jeweils das letzte Posting aus den entsprechenden Threads gesucht ... ^^
.
 
Zurück