Проблемът с "последните на група" е изключително често срещан в SQL. Само на този сайт има безброй примери за решения на този проблем.
Ако вашите времеви марки са уникални за активност на членове:
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)
алтернативно, ако вашият идентификационен номер на активност се увеличава монотонно с времето:
...
WHERE
a.id = (SELECT MAX(id) FROM activities WHERE member_id = m.id)
Не е нужно да групирате. Но заявката ще се възползва от индекс на activities
над (member_id, timestamp)
или (member_id, id)
, съответно.
РЕДАКТИРАНЕ
За да покажете всички членове, които не са регистрирали дейност, използвайте ляво присъединяване по този начин.
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)
Имайте предвид, че няма WHERE
клауза. Семантично WHERE се прилага след съединенията са готови. Така че клауза WHERE би премахнала редовете, които LEFT JOIN добави, което на практика дава същия резултат като оригиналното INNER JOIN.
Но ако приложите допълнителния предикат точно в условието за присъединяване, LEFT JOIN ще работи според очакванията.