Problem „najnowszy na grupę” jest niezwykle powszechne w SQL. W samej tej witrynie istnieje niezliczona ilość przykładów rozwiązań tego problemu.
Jeśli Twoje sygnatury czasowe są unikalne na aktywność członka:
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)
alternatywnie, jeśli identyfikator Twojej aktywności rośnie monotonicznie z czasem:
...
WHERE
a.id = (SELECT MAX(id) FROM activities WHERE member_id = m.id)
Nie musisz się grupować. Ale zapytanie skorzysta z indeksu activities
ponad (member_id, timestamp)
lub (member_id, id)
, odpowiednio.
EDYTUJ
Aby wyświetlić członków, którzy nie zarejestrowali aktywności, użyj lewego dołączenia w ten sposób.
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)
Zauważ, że nie ma WHERE
klauzula. Semantycznie GDZIE jest stosowane po sprzężenia są gotowe. Tak więc klauzula WHERE usunęłaby wiersze dodane przez LEFT JOIN, dając w efekcie ten sam wynik, co oryginalny INNER JOIN.
Ale jeśli zastosujesz dodatkowe prawo predykatu w warunku dołączenia, LEFT JOIN będzie działać zgodnie z oczekiwaniami.