Hallo,
Ich bin soweit gekommen:
SELECT
meldungen.msgid,
/* ...Weitere Daten aus der meldungen-Tabelle... */
benutzer.vorname,
benutzer.nachname,
/* ...Evtl. weitere Daten aus der benutzer-Tabelle... */
COUNT(kommentare.msgid) AS kommentarzahl
FROM meldungen
LEFT JOIN benutzer ON meldungen.loginname=benutzer.loginname
LEFT JOIN kommentare ON meldungen.msgid=kommentare.msgid
WHERE meldungen.sichtbar="1"
GROUP BY meldungen.msgid
ORDER BY meldungen.aenderung DESCDamit bekomme ich die Meldungsdaten, die zugehörigen Benutzerdaten und die jeweilige Kommentarzahl in einem Datensatz.
Das funktioniert soweit in den getesteten Fällen (Kommentare/keine Kommentare, Benutzer vorhanden/Benutzer nicht vorhanden, ...)
Es gibt also wirklich in der Tabelle meldungen Einträge, zu denen es keine Entsprechungen in der Tabelle benutzer gibt? Also Meldungen von nicht vorhandenen Benutzern? Outer-Joins, wie LEFT JOIN und RIGHT JOIN, sind nämlich in jedem Fall langsamer als INNER JOINs. Sollte meine Frage also mit Nein zu beantworten sein, wäre folgendes besser:
SELECT
meldungen.msgid,
benutzer.vorname,
benutzer.nachname,
Count(kommentare.msgid) AS AnzahlKommentare
FROM
(meldungen INNER JOIN benutzer ON meldungen.loginname = benutzer.loginname)
LEFT JOIN kommentare ON meldungen.msgid = kommentare.msgid
GROUP BY meldungen.msgid, benutzer.vorname, benutzer.nachname;
Die vielen Felder nach GROUP BY sind so nach SQL vorgeschrieben. Demnach muss in gruppierten Abfragen jedes Feld entweder zur Grupperung gehören oder Teil einer Aggregatfunktion sein. Es ginge also auch so:
SELECT meldungen.msgid, First(benutzer.vorname) AS ErsterVorname, First(benutzer.nachname) AS ErsterNachname, Count(kommentare.msgid) AS AnzahlKommentare
FROM (meldungen INNER JOIN benutzer ON meldungen.loginname = benutzer.loginname) LEFT JOIN kommentare ON meldungen.msgid = kommentare.msgid
GROUP BY meldungen.msgid;
Wobei ich jetzt nicht weiß, ob MySQL die Aggregatfunktion First() kennt. MySQL akzeptiert die Abfrage auch so, wie Du sie gruppiert hast, nimmt aber auch ohne explizite Aggregatfunktion jeweils den ersten Wert der Felder, nach denen nicht gruppiert wird.
Wenn meine Frage mit Ja zu beantworten ist, geht es natürlich nur so, wie Du es bereits machst. Dann vergiss aber nicht Indexe auf die Felder zu setzen, die zu den JOIN-Verknüpfungen gehören und nach denen gruppiert und sortiert wird.
viele Grüße
Axel