【发布时间】:2011-08-11 20:46:18
【问题描述】:
我有 2 张桌子。 Person 表和activity_log 表
每个人都有很多活动。
我想“选择”一个“人员”列表,显示他们上次活动的活动名称和活动日期。 (并非所有活动)
Person 表有 person_id、name、email
活动表有person_id、activity_id、activity_date、activity_name
提前感谢您的帮助。
【问题讨论】:
我有 2 张桌子。 Person 表和activity_log 表
每个人都有很多活动。
我想“选择”一个“人员”列表,显示他们上次活动的活动名称和活动日期。 (并非所有活动)
Person 表有 person_id、name、email
活动表有person_id、activity_id、activity_date、activity_name
提前感谢您的帮助。
【问题讨论】:
子查询应该可以解决问题:
SELECT p.person_id, p.name, p.email, a.activity_id, a.activity_date, a.activity_name
FROM Person p
LEFT JOIN Activity a
ON p.person_id = a.person_id
WHERE a.activity_date = (SELECT MAX(a1.activity_date)
FROM activity a1
WHERE a.person_id = a1.person_id
GROUP BY person_id) OR activity_date IS NULL;
【讨论】:
LEFT JOIN,而不是INNER JOIN。我会编辑。
假设您的 ID 是自动编号的,您会这样做:
SELECT pe.person_id,
pe.name,
al.activity_name,
al.activity_date
FROM person pe
LEFT JOIN (SELECT p.person_id,
Max(a.activity_id) activity_id
FROM person p
LEFT JOIN activity_log a
ON ( p.person_id = a.person_id )
GROUP BY p.person_id) AS LAST
ON pe.person_id = LAST.person_id
LEFT JOIN activity_log al
ON LAST.activity_id = al.activity_id
但是,用户可能会比新的活动更晚进入过去的活动,那么这将失败,您必须这样做:
SELECT LAST.person_id,
LAST.name,
LAST.activity_date,
(SELECT activity_name
FROM activity_log al
WHERE al.person_id = LAST.person_id
AND al.activity_date = LAST.activity_date) activity_name
FROM (SELECT p.person_id,
Max(p.name) AS name,
Max(a.activity_date) activity_date
FROM person p
LEFT JOIN activity_log a
ON ( p.person_id = a.person_id )
GROUP BY p.person_id) AS LAST
但这仍然有一个问题:由于 MySQL 不允许在子查询中使用 LIMIT,如果同一个人有两个具有相同 activity_date 的活动并且这是最新日期,则查询将失败。
【讨论】: