「グループごとの最新」の問題は非常に 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)
または、アクティビティ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が追加した行を削除し、元のINNERJOINと同じ結果を効果的に提供します。
ただし、結合条件で追加の述語を適用すると、LEFTJOINは期待どおりに機能します。