我有一个training_stats表(当前应接受的培训),我也有一个completed_training表。
我想做的是查询已完成表格中最后一次完成日期的培训。
我几乎有想要的东西,我接受了应有的培训,但是它们与每个已完成的记录重复(因为每个当前到期的记录都有很多已完成的记录),我只想要单行和最新的完成日期
我一直在尝试使用MAX,当我独立运行MAX查询时,我得到了最后一条记录。但是当MAX查询处于联接状态时,它将返回所有已完成的行。
这是我正在使用的查询:
SELECT s.course_stat_id
,o.org_name
,u.id
,u.first_name
,u.last_name
,a.area_id
,a.area_name
,tc.course_id
,tc.course_name
,s.assigned_on
,s.due
,s.pass_mark
,s.completed_on
,completed.complete_training_id
,completed.complete_date
FROM training_stats s
JOIN organisations o ON o.org_id = s.org_id
LEFT JOIN (
SELECT complete_training_id
,user_id
,area_id
,course_id
,max(completed_on) AS complete_date
FROM completed_training
GROUP BY complete_training_id
) completed ON completed.user_id = s.user_id
AND completed.area_id = s.area_id
AND completed.course_id = s.course_id
LEFT JOIN users u ON u.id = s.user_id
LEFT JOIN areas a ON a.area_id = s.area_id
LEFT JOIN training_courses tc ON tc.course_id = s.course_id
WHERE u.active = 1
AND o.active = 1
AND s.assigned = 1
你能看到我在做什么错吗?
答案 0 :(得分:0)
我不太确定这一点。首先,运行此查询。它应该列出所有已完成的培训,其rnk从1(最新)到n(最旧)。
SELECT complete_training_id
,user_id
,area_id
,course_id
,completed_on AS complete_date
,@curRank := case when complete_training_id <> @cur_complete_training_id then 0 else @curRank + 1 end rnk
FROM completed_training, (select @curRank := 0, @cur_complete_training_id := 0)
ORDER BY complete_training_id, completed_on DESC
如果为真,答案是:
SELECT s.course_stat_id
,o.org_name
,u.id
,u.first_name
,u.last_name
,a.area_id
,a.area_name
,tc.course_id
,tc.course_name
,s.assigned_on
,s.due
,s.pass_mark
,s.completed_on
,completed.complete_training_id
,completed.complete_date
FROM training_stats s
JOIN organisations o ON o.org_id = s.org_id
LEFT JOIN (
SELECT complete_training_id
,user_id
,area_id
,course_id
,completed_on AS complete_date
,@curRank := case when complete_training_id <> @cur_complete_training_id then 0 else @curRank + 1 end rnk
FROM completed_training, (select @curRank := 0, @cur_complete_training_id := 0)
ORDER BY complete_training_id, completed_on DESC
) completed ON completed.user_id = s.user_id and completed.rnk = 1
AND completed.area_id = s.area_id
AND completed.course_id = s.course_id
LEFT JOIN users u ON u.id = s.user_id
LEFT JOIN areas a ON a.area_id = s.area_id
LEFT JOIN training_courses tc ON tc.course_id = s.course_id
WHERE u.active = 1
AND o.active = 1
AND s.assigned = 1
答案 1 :(得分:0)
并非完全符合您的预期结果,但是失败的原因可能是您的组by和JOIN。您的分组依据仅是培训ID,但是您也要提取用户,区域和课程以及相应的培训ID,用户,区域,课程的完成日期。您的分组方式和加入方式应符合其独特特征。
在没有看到数据的情况下,据我解释,查询是“ complete_training_id”是该表的自动增量列。话虽如此,该ID永远只有一条记录。
话虽如此,完整的培训表可以为单个用户,区域和课程提供您想要最近的多个培训日。例如,某人上大学并需要参加许多计算机课程,并且他们是以前的进修课程,因此假定所有课程都是相同的课程ID。一个人可以参加2012年,2014年,2016年。您想要显示2016年培训日期的用户/区域/课程实例。因此,让我们先来看一下。
select
ct.user_id,
ct.area_id,
ct.course_id,
max(ct.completed_on) AS complete_date
FROM
completed_training ct
GROUP BY
ct.user_id,
ct.area_id,
ct.course_id
现在,对于每个用户,每个领域和学习课程,我都有一个记录,其中包含最近的完成日期。现在让我们拉出其余的细节,但是由于您也需要完整的培训ID,因此我在下面的查询中应用了该ID。默认情况下,每次添加新记录时,ID都会增加,因此一年前完成的记录的值将比今天完成的ID低。因此,您将获得给定用户,区域,课程的完整ID及其对应的日期。
SELECT
s.course_stat_id,
o.org_name,
u.id,
u.first_name,
u.last_name,
a.area_id,
a.area_name,
tc.course_id,
tc.course_name,
s.assigned_on,
s.due,
s.pass_mark,
s.completed_on,
ct.complete_training_id,
ct.complete_date
FROM
training_stats s
JOIN organisations o
ON s.org_id = o.org_id
AND o.active = 1
LEFT JOIN
( select
ct.user_id,
ct.area_id,
ct.course_id,
max(ct.complete_training_id ) as complete_training_id,
max(ct.completed_on) AS complete_date
FROM
completed_training ct
GROUP BY
ct.user_id,
ct.area_id,
ct.course_id ) ct
on s.user_id = ct.user_id
AND s.area_id = ct.area_id
AND s.course_id = ct.course_id
JOIN users u
ON s.user_id = u.id
AND u.active = 1
LEFT JOIN areas a
ON s.area_id = a.area_id
LEFT JOIN training_courses tc
ON s.course_id = tc.course_id
WHERE
s.assigned = 1