【问题标题】:Build a query to assign trainings to staff构建查询以将培训分配给员工
【发布时间】:2018-01-30 05:11:56
【问题描述】:

这个问题自从我最初发布以来已经更新,感谢最初的回答者的帮助,我已经取得了一些进展,但仍然不完全在那里,无法弄清楚以下内容。

我有一个分配了角色的员工列表。每卷都需要完成一组不同的培训。会话以输入到名为“TrainingSessions”的表的形式记录。我想从“员工”表中获取姓名列表,并将其与“TrainingSessions”中的出勤率进行比较,并输出未参加所需培训课程的人员列表。

我已成功创建了一个查询,该查询提取员工姓名(和相关 ID)并将其与分配给他们的角色所需的培训一起列出。

SELECT Employees.ID, Employees.LastName, Employees.FirstName, Trainings.ID, Trainings.TrainingTitle
FROM (EmployeeRoles INNER JOIN Employees ON EmployeeRoles.ID = Employees.Role) INNER JOIN Trainings ON EmployeeRoles.ID = Trainings.RequiredFor.Value
GROUP BY Employees.ID, Employees.LastName, Employees.FirstName, Trainings.ID, Trainings.TrainingTitle, Employees.Resignation
HAVING (((Employees.Resignation) Is Null));

我还创建了一个查询,将 TrainingSessions 展平,以便每个与会者都列在自己的行上。

SELECT TrainingSessions.TrainingTitle AS Title, TrainingSessions.SessionDate AS [Date], TrainingSessions.Attendance.Value AS Who, DateAdd("yyyy",[Trainings]![YearsValid],[SessionDate]) AS Due
FROM Trainings INNER JOIN TrainingSessions ON Trainings.ID = TrainingSessions.TrainingTitle
ORDER BY TrainingSessions.SessionDate;

我现在需要弄清楚如何将所需的培训与已完成的培训进行比较,并列出尚未完成特定培训的员工名单。到目前为止,我能得到的最接近的结果是列出了每个员工所需的培训列表,这些培训从未参加过会议,而不是特定员工没有参加过的培训。

以下是我的数据库现在的一些图片:

【问题讨论】:

  • 你能展示你开始使用的三个表吗?由此,您应该能够准备所需培训和已完成培训的列表,然后比较这两个列表。看看你到目前为止所拥有的会有所帮助。
  • 尝试使用 Access 查询生成器查找不匹配的查询向导。
  • 我在问题中添加了表格的图片。我知道其中两个表具有多值查找字段,但我想不出办法。

标签: ms-access


【解决方案1】:

我认为你的问题不仅仅是这个查询。首先,TrainingSessions 中的员工姓名似乎不一致 - 有些只有姓氏,有些只有姓氏和名字。目前尚不清楚它们是否会与 Employee 表匹配。其次,在某些情况下,Trainings 中的 RequiredFor 字段看起来像是列出了多个值 - 因此与员工的匹配并不明确。我假设它应该匹配 Role 字段,并且 Role 将始终匹配 Trainings 表中的拼写等 - 但从列表中提取它们仍然是一个额外的步骤。第三,您在培训中有一个 YearsValid 字段,因此假设您不仅需要检查出勤率,还需要检查日期 - 也不需要在您的问题中。第四,您在 TrainingSessions 中有注释说“没有参加过课程”——它们需要被排除在外吗?

所以要开始,我认为您需要考虑构建三个查询。

首先是必修课程列表。您最终需要一个包含员工(最好带有 ID,而不仅仅是名称)和必修课程(同样带有课程 ID)以及可能是 YearsValid 信息的表格。每个员工的每个要求可能需要 1 条记录 - 而不是一条记录中的多个要求。只要员工中的角色与培训中的角色相匹配,从您拥有的数据中组装起来并不难。将此另存为 TrainingRequired。

SELECT Employees.ID AS EmployeeID, Employees.FirstName, Employees.LastName, Employees.Role, Trainings.ID AS TrainingID, Trainings.TrainingTitle, Trainings.YearsValid
FROM Employees, Trainings
WHERE (((InStr([RequiredFor],[Role]))>0));

然后,您需要对已完成的课程进行另一个查询。假设员工姓氏是唯一的,并且 TrainingSessions 表至少包含正确的姓氏,这样的事情会起作用。请注意,在大多数情况下,这是一个非常糟糕的假设,因此您可能需要一种不同的方式将员工 ID 获取到此查询中。我也没有对备注栏中的信息进行任何调整。将此另存为 TrainingCompleted。

SELECT Employees.ID AS EmployeeID, Employees.FirstName, Employees.LastName, Employees.Role, TrainingSessions.TrainingTitle AS TrainingID, TrainingSessions.SessionDate, TrainingSessions.Attendance
FROM Employees, TrainingSessions
WHERE (((InStr([Attendance],[LastName]))>0));

一旦这 2 个查询都正常工作并且同时具有 EmployeeID 和 TrainingID,您可以将它们放在一起以获得您需要的内容。

SELECT TrainingRequired.EmployeeID, TrainingRequired.FirstName, TrainingRequired.LastName, TrainingRequired.Role, TrainingRequired.TrainingID, TrainingRequired.TrainingTitle, TrainingCompleted.SessionDate, IIf((Now()-[SessionDate])/365<=[YearsValid],"X") AS [Current]
FROM TrainingRequired LEFT JOIN TrainingCompleted ON (TrainingRequired.TrainingID = TrainingCompleted.TrainingID) AND (TrainingRequired.EmployeeID = TrainingCompleted.EmployeeID);

此最终查询会检查每个要求以查看课程是否已参加并且是否仍在 YearsValid 标准内。如果是这样,最后一列是“X”。如果不是,则最后一列为空白。如果需要,您可以进一步过滤以仅查看缺少的要求。

【讨论】:

  • 我会试试这个。我的表格中的多值列表(自从我发布这些图片之后)已转换为文本列表,现在显示表格中的关联键。必填字段与角色表中的 ID 相关(我没有显示)。出勤字段与员工表中的 ID 字段相关(我没有显示)。 “未参加课程”就在那里,因为我正在考虑手动添加培训日期以产生截止日期。谢谢您的意见。我会告诉你进展如何。
  • 好 - 听起来对我提供的内容进行了一些小改动,应该可以满足您的需求。请告诉我进展如何。
  • 我马上就遇到了一个错误。它说不能在 WHERE 或 HAVING 子句中使用多值字段 'required for'。所以,多值字段是问题,但我不知道如何使用多值字段。
  • 更改了问题中的图片以显示将组合框更改为文本框后培训表现在的显示方式
  • 对所有 cmets 感到抱歉,但我注意到我的一些表可能没有正确运行,因为我消除了其中的查找方式。我已经重新构建了数据库(现在其中的信息更少),希望这次我完成它的方式可以让它更好地工作。我更新了图片以反映新数据库。
【解决方案2】:

我做到了!!!

首先:我创建了一个查询,它输出一个平面表,将每个员工所需的所有培训放在单独的一行上:

SELECT TrainingRequiredByName.Employees.ID AS EmpID, TrainingRequiredByName.Trainings.ID AS TrainID, TrainingRequiredByName.Employees.LastName AS [Last], TrainingRequiredByName.Employees.FirstName AS [First], TrainingRequiredByName.Trainings.TrainingTitle AS Title
FROM TrainingRequiredByName;

然后我创建了一个查询,该查询输出一个平面表,将所有已完成的训练放在单独的行上:

SELECT Employees.ID AS EmpID, Trainings.ID AS TrainID, Employees.LastName AS [Last], Employees.FirstName AS [First], Trainings.TrainingTitle AS Title
FROM Trainings INNER JOIN (Employees INNER JOIN TrainingSessions ON Employees.ID = TrainingSessions.Attendance.Value) ON Trainings.ID = TrainingSessions.TrainingTitle;

然后我做了一个 find unmatched 查询,比较每个查询的 EmpID 和 TrainID 并输出我一直在搜索的列表!

感谢 Don George 帮助我朝着正确的方向前进。我无法告诉你我有多么兴奋得到一个我可以实际使用的结果!

【讨论】:

  • 太棒了!我知道这种感觉,很高兴能够提供帮助。
猜你喜欢
  • 2011-07-07
  • 1970-01-01
  • 2022-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多