我有两个表(成员和活动),我正在尝试使用每个成员的最新活动查询成员.我已经使用了两个查询(一个用于获取成员,第二个用max(id)和group by(成员)在活动上)和一些代码来合并数据.我确定它可以通过一个查询来完成,但我无法完成它.有任何想法吗?
会员表
id, name
1, Shawn
2, bob
3, tom
Run Code Online (Sandbox Code Playgroud)
活动表
id, member_id, code, timestamp, description
1, 1, 123, 15000, baked a cake
2, 1, 456, 20000, ate dinner
3, 2, 789, 21000, drove home
4, 1, 012, 22000, ate dessert
Run Code Online (Sandbox Code Playgroud)
期望的结果:
id, name, activity_code, activity_timestamp, activity_description
1, shawn, 012, 22000, ate dessert
2, bob, 789, 21000, drove home
3, tom, null, null, null
Run Code Online (Sandbox Code Playgroud)
Tom*_*lak 29
"每组最新"问题在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)
Run Code Online (Sandbox Code Playgroud)
或者,如果您的活动ID随时间单调增加:
...
WHERE
a.id = (SELECT MAX(id) FROM activities WHERE member_id = m.id)
Run Code Online (Sandbox Code Playgroud)
你不需要分组.但是查询将分别受到activities
over (member_id, timestamp)
或index的索引的影响(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)
Run Code Online (Sandbox Code Playgroud)
请注意,没有WHERE
条款.在语义上,在完成连接之后应用WHERE .因此,WHERE子句将删除LEFT JOIN添加的行,从而有效地给出与原始INNER JOIN相同的结果.
但是如果在连接条件中应用附加谓词,则LEFT JOIN将按预期工作.
SELECT
members.id ,
members.name,
activities.code AS activity_code,
activities.timestamp AS activity_timestamp,
activities.description AS activity_description
FROM
members
LEFT JOIN activities
ON members.id = activities.member_id
LEFT JOIN
(
SELECT
activities.member_id
MAX(activities.id) AS id
FROM activities
GROUP BY
activities.member_id
) AS t1
ON activities.id = t1.id
WHERE
t1.id IS NOT NULL
Run Code Online (Sandbox Code Playgroud)