mysql表连接聚合

时间:2011-08-11 20:46:18

标签: mysql sql select

我有2张桌子。 Person表和activity_log

每个人都有很多活动。

我想“选择”显示其上一个活动的activity_name和activity_date的“人员”列表。 (并非所有活动)

人员表有person_id,姓名,电子邮件

活动表包含person_id,activity_id,activity_date,activity_name

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

假设您的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并且这是最新日期,则查询将失败。

答案 1 :(得分:1)

子查询应该可以解决问题:

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;