Det "senaste per grupp"-problemet är extremt vanligt i SQL. Det finns otaliga exempel på lösningar på just detta problem bara på den här webbplatsen.
Om dina tidsstämplar är unika per medlemsaktivitet:
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)
alternativt, om ditt aktivitets-ID ökar monotont med tiden:
...
WHERE
a.id = (SELECT MAX(id) FROM activities WHERE member_id = m.id)
Du behöver inte gruppera. Men frågan kommer att dra nytta av ett index över activities
över (member_id, timestamp)
eller (member_id, id)
, respektive.
REDIGERA
För att visa medlemmar som inte har loggat en aktivitet, använd en vänsteranslutning så här.
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)
Observera att det inte finns någon WHERE
klausul. Semantiskt tillämpas WHERE efter sammanfogningarna är gjorda. Så en WHERE-sats skulle ta bort raderna som LEFT JOIN lade till, vilket i praktiken ger samma resultat som den ursprungliga INNER JOIN.
Men om du använder det extra predikatet höger i anslutningsvillkoret kommer LEFT JOIN att fungera som förväntat.