Vấn đề "mới nhất cho mỗi nhóm" là cực kỳ phổ biến trong SQL. Có vô số ví dụ về các giải pháp cho vấn đề này chỉ riêng trên trang web này.
Nếu dấu thời gian của bạn là uniqe cho mỗi hoạt động thành viên:
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)
cách khác, nếu ID hoạt động của bạn đang tăng đơn điệu theo thời gian:
...
WHERE
a.id = (SELECT MAX(id) FROM activities WHERE member_id = m.id)
Bạn không cần phải nhóm. Nhưng truy vấn sẽ được hưởng lợi từ một chỉ mục về các hoạt động activities
over (member_id, timestamp)
hoặc (member_id, id)
, tương ứng.
CHỈNH SỬA
Để hiển thị bất kỳ thành viên nào chưa đăng nhập một hoạt động, hãy sử dụng tham gia bên trái như thế này.
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)
Lưu ý rằng không có WHERE
mệnh đề. Về mặt ngữ nghĩa, WHERE được áp dụng sau các phép nối đã xong. Vì vậy, mệnh đề WHERE sẽ loại bỏ các hàng mà LEFT JOIN đã thêm vào, cho kết quả tương tự như INNER JOIN ban đầu.
Nhưng nếu bạn áp dụng vị từ bổ sung ngay trong điều kiện kết hợp, LEFT JOIN sẽ hoạt động như mong đợi.