2

我有 3 张桌子:

member
member_id|member_name

training_member
training_id|member_id

training
training_id|team_id|training_date

我需要找到最新的培训,每个成员都有 team_id 和 training_date。如果成员没有接受任何培训,则应返回 NULL 作为 team_id 和 training_date

我尝试了很多不同的方法,比如:

SELECT m.member_id, t.team_id, MAX(t.training_date)
FROM member m
JOIN training_member tm ON m.member_id = tm.member_id
JOIN training t ON tm.training_id = t.training_id
GROUP BY m.member_id
ORDER BY m.member_name, t.training_date DESC

但它没有给出正确的结果,它似乎返回列出的第一个 team_id 而不是与 MAX(training_date) 关联的那个

我需要改变什么?

编辑:sqlfiddle:http ://sqlfiddle.com/#!2/a1ec1/1

4

3 回答 3

3

可能是这样的:-

SELECT m.member_id, Sub2.team_id, Sub2.MaxTrainingDate
FROM member m
LEFT OUTER JOIN 
(
    SELECT tm.member_id, t.team_id, Sub1.MaxTrainingDate
    FROM training_member tm 
    INNER JOIN training t ON tm.training_id = t.training_id
    INNER JOIN 
    (
        SELECT tm.member_id, MAX(t.training_date) AS MaxTrainingDate
        FROM training_member tm 
        LEFT OUTER JOIN training t ON tm.training_id = t.training_id
        GROUP BY tm.member_id
    ) Sub1
    ON Sub1.member_id = tm.member_id
    AND Sub1.MaxTrainingDate = t.training_date
) Sub2
ON Sub2.member_id = m.member_id
ORDER BY m.member_name, MaxTrainingDate DESC

使用内部选择来获取每个成员的最新培训,将其与培训成员和培训表连接以获取其他详细信息(即 team_id),然后针对成员 LEFT JOIN(以应对未受过培训的成员)。

编辑 - 删除子查询并将它们放入视图以允许主 SQL 成为视图。

查看以获取每个成员的最大培训日期

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vw_max_training` AS select `tm`.`member_id` AS `member_id`,max(`t`.`training_date`) AS `MaxTrainingDate` from (`training_member` `tm` left join `training` `t` on((`tm`.`training_id` = `t`.`training_id`))) group by `tm`.`member_id`;

查看以获取每个成员的最大培训日期的团队详细信息

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vw_max_training_team` AS select `tm`.`member_id` AS `member_id`,`t`.`team_id` AS `team_id`,`sub1`.`MaxTrainingDate` AS `MaxTrainingDate` from ((`training_member` `tm` join `training` `t` on((`tm`.`training_id` = `t`.`training_id`))) join `vw_max_training` `sub1` on(((`sub1`.`member_id` = `tm`.`member_id`) and (`sub1`.`MaxTrainingDate` = `t`.`training_date`))));

最终视图

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vw_main` AS select `m`.`member_id` AS `member_id`,`sub2`.`team_id` AS `team_id`,`sub2`.`MaxTrainingDate` AS `MaxTrainingDate` from (`member` `m` left join `vw_max_training_team` `sub2` on((`sub2`.`member_id` = `m`.`member_id`))) order by `m`.`member_name`,`sub2`.`MaxTrainingDate` desc;
于 2013-10-23T09:29:10.630 回答
0

检查这个

SELECT * FROM member LEFT JOIN 
(SELECT training.training_id,team_id,max(training_date) as training_date, 
member_id FROM training LEFT JOIN training_member ON 
training.training_id = training_member.training_id GROUP BY member_id) a 
ON member.member_id = a.member_id
于 2013-10-23T09:48:20.637 回答
0

如果会员没有接受过任何培训,则用于LEFT JOIN返回。null

这是代码:

SELECT m.member_id, t.team_id, max(t.training_date)
FROM member m
LEFT  JOIN training_member tm ON m.member_id = tm.member_id
LEFT  JOIN training t ON tm.training_id = t.team_id
GROUP BY tm.member_id
ORDER BY m.member_name, t.training_date DESC

演示: http ://sqlfiddle.com/#!2/a1ec1/42

于 2013-10-23T09:54:32.473 回答