Das "neueste pro Gruppe"-Problem ist extrem in SQL üblich. Allein auf dieser Seite gibt es unzählige Lösungsbeispiele für genau dieses Problem.
Wenn Ihre Zeitstempel pro Mitgliedsaktivität eindeutig sind:
SELECT
m.id,
m.name,
a.code activity_code,
a.timestamp activity_timestamp,
a.description activity_description
FROM
members m
INNER JOIN activities a ON a.member_id = m.id
WHERE
a.timestamp = (SELECT MAX(timestamp) FROM activities WHERE member_id = m.id)
alternativ, wenn Ihre Aktivitäts-ID mit der Zeit monoton ansteigt:
...
WHERE
a.id = (SELECT MAX(id) FROM activities WHERE member_id = m.id)
Sie müssen nicht gruppieren. Aber die Abfrage profitiert von einem Index für activities
über (member_id, timestamp)
oder (member_id, id)
.
BEARBEITEN
Um alle Mitglieder anzuzeigen, die keine Aktivität angemeldet haben, verwenden Sie einen linken Join wie diesen.
SELECT
m.id,
m.name,
a.code activity_code,
a.timestamp activity_timestamp,
a.description activity_description
FROM
members m
LEFT JOIN activities a ON
a.member_id = m.id
AND a.timestamp = (SELECT MAX(timestamp) FROM activities WHERE member_id = m.id)
Beachten Sie, dass es kein WHERE
gibt Klausel. Semantisch wird WHERE nach angewendet Die Verbindungen sind fertig. Eine WHERE-Klausel würde also die Zeilen entfernen, die der LEFT JOIN hinzugefügt hat, und effektiv das gleiche Ergebnis wie der ursprüngliche INNER JOIN liefern.
Aber wenn Sie das zusätzliche Prädikat rechts in der Join-Bedingung anwenden, funktioniert der LEFT JOIN wie erwartet.