Das Problem ist auf eine MySQL-spezifische Erweiterung des Verhaltens von GROUP BY
zurückzuführen Klausel. Andere Datenbanken würden einen Fehler ausgeben ... so etwas wie On-Aggregate in der SELECT-Liste". (Wir können MySQL dazu bringen, einen ähnlichen Fehler auszugeben, wenn wir ONLY_FULL_GROUP_BY in sql_mode einbeziehen.)
Das Problem mit dem Ausdruck messages.created
bezieht sich auf einen Wert aus einer unbestimmten Zeile in GROUP BY. Die ORDER BY-Operation erfolgt viel später in der Verarbeitung, nach der GROUP BY-Operation.
Verwenden Sie ein Aggregat, um das "Neueste" für jede Gruppe erstellt zu bekommen Ausdruck MAX(messages.created)
.
Die anderen Werte aus derselben Zeile zu erhalten, ist etwas komplizierter.
Angenommen, dass created
ist einzigartig innerhalb einer bestimmten conversation_id
group (oder, wenn es nicht garantiert ist, dass es nicht eindeutig ist, und Sie damit einverstanden sind, mehrere Zeilen mit demselben Wert für created
zurückzugeben ...
Um den neusten created
zu erhalten für jede conversation_id
SELECT lm.conversation_id
, MAX(lm.created) AS created
FROM conversation lc
JOIN message lm
ON lm.conversation_id = lc.id
WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
GROUP BY lm.conversation_id
Sie können dies als Inline-Ansicht verwenden, um die gesamte Zeile mit diesem zuletzt created
zu erhalten
SELECT c.*
, m.*
FROM ( SELECT lm.conversation_id
, MAX(lm.created) AS created
FROM conversation lc
JOIN message lm
ON lm.conversation_id = lc.id
WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
GROUP BY lm.conversation_id
) l
JOIN conversation c
ON c.id = l.conversation_id
JOIN messages m
ON m.conversation_id = l.conversation_id
AND m.created = l.created
WHERE (c.creator_id = :userId OR c.to_id = :userId)
HINWEISE:
Sie können einen ORDER BY
hinzufügen -Klausel, um die zurückgegebenen Zeilen nach Bedarf anzuordnen.
Das WHERE
-Klausel in der äußeren Abfrage ist wahrscheinlich redundant und unnötig.
Wir ziehen es vor, SELECT *
zu vermeiden , und ziehen es vor, die zurückzugebenden Ausdrücke explizit aufzulisten.