我的公司派人去接受培训。根据预计的新员工/转职计划,我被要求生成一份报告,估算每个课程所需的席位数量。按季度划分。
问题:我的问题是双重的:
期望输出:
ID PersonnelID CourseID ProjectedStartDate ProjectedEndDate
1 1 1 1/14/2017 1/14/2017
2 2 1 2/17/2017 2/17/2017
3 2 2 2/18/2017 2/19/2017
4 2 3 2/20/2017 2/20/2017
5 3 49 1/18/2017 2/03/2017
6 …
背景信息:课程按顺序进行:前几门课程是公司的入门课程,后面的课程更专门针对员工的工作。有超过50种不同的课程,40种不同的工作,我们正在预测~1k新招聘/转学。每个工作角色必须按照规定的顺序进行一系列课程,但是我在表示此顺序并随后编写必要的查询时遇到问题。
现有表格
我有几张用于存储数据的表格:Personnel
,LnkPersonnelToWorkroles
,Workroles
,LnkWorkrolesToCourses
和Courses
(其中&#39还有很多其他人,但为了确定这个问题,我省略了它们。以下是这些表中的一些名义数据:
人员(这些是预计的新员工及其预计到达日期。)
ID DisplayName RequiredCompletionDate
1 Kristel Bump 10/1/2016
2 Shelton Franke 3/11/2017
3 Shaunda Launer 4/16/2017
4 Clarinda Kestler 3/13/2017
5 My Wimsatt 6/6/2017
6 Gillian Bramer 10/25/2016
7 ...
Workroles (这些是公司的职位)
ID Workrole
1 Manager
2 Secretary
3 Admin Asst.
4 ...
LnkPersonnelToWorkroles (将预计的新员工投入预计的工作量)
ID PersonnelID WorkroleID
1 1 1
2 2 1
3 3 1
4 4 1
5 5 1
6 6 1
7 ...
课程(所有课程均可)
ID CourseName LengthInDays
1 Orientation 1
2 Email Etiquette 2
3 Workplace Safety 1
4 ...
LnkWorkrolesToCourses (将工作场所与多对多关系中的必修课程联系起来)
ID WorkroleID CourseID
1 1 1
2 2 1
3 2 2
4 2 3
5 3 49
6 ...
思考:我的方法是首先根据新员工的目标完成日期和工作时间制定逐个人的时间表。然后,对于每个班级,我可以总结那个季度开始的新员工人数。
我考虑过以我能想到的最普遍的方式来表示课程(即使用有向无环图),但由于大多数课程只有一门必修课程,我认为这样做了#39 ;使用下面的Prerequisites
表更容易表示先决条件;但是,我不知道如何在查询中使用它。
先决条件(这是一个好主意吗?)
ID CourseID PrereqCourseID
1 2 1
2 3 1
3 4 1
4 5 4
5 ...
注意:我目前不关心这些日子是否实际提供课程;一旦我们知道每个季度我们需要多少,我们就会计算出课程安排。现在,我们正在尝试估算每门课程的需求。
编辑1:澄清期望输出表:如果此人在第D天开始课程1,那么他们无法开始课程2直到他们完成课程1,即直到明天。对于长度L> 1天的课程,后续课程的开始日期延迟L天。请注意此效果在 Desired Output 表中为workrole ID 2播放:他预计将于2月17日到达,同一天开始并完成课程1,第二天开始课程2(2 / 18),并在那之后的第二天(2月19日)完成课程2。
答案 0 :(得分:0)
我发布这个答案是因为它给了我一个近似的解决方案;其他答案仍然欢迎。
我完全避免了一个先决条件表,并选择了一种更简单的方法:partial ordering个课程。
首先,我画了prerequisite tree;它看起来与此图像类似:
我根据先决条件树中的深度定义了partial ordering个课程。在上图中,CHM124和High School Chem w / Lab优先级为1,CHM152优先级为2,CHM230优先级为3,CHM260和CHM 270优先级为4,依此类推......此部分排序存储在{ {1}}表:
CoursePriority:
CoursePriority
因此,不会同时进行两门课程,我使用以下更新查询以一个小的随机数扰乱每门课程的优先级:
ID CourseID Priority
1 1 1
2 2 2
3 3 3
4 4 3
5 5 4
6 6 3
7 ...
(我使用UPDATE CoursePriority SET CoursePriority.Priority = [Priority]+Rnd([ID])/1000;
作为[ID]
方法的输入,以确保每个课程都被一个不同的随机数扰乱。)我最终得到了这个:
Rnd
上面的方法回答了我的第一个问题" 在关系数据库中表示一系列课程(即先决条件)的最佳[合理]方式是什么?"现在至于生成课程安排......
首先,我创建了一个查询ID CourseID Priority
1 1 1.000005623
2 2 2.000094955
3 3 3.000036401
4 4 3.000052486
5 5 4.000076711
6 6 3.00000535
7 ...
,以便将qryLnkCoursesPriorities
链接到Courses
表:
CoursePriority
结果:
SELECT Courses.ID AS CourseID, Courses.DurationInDays, CoursePriority.Priority
FROM Courses INNER JOIN CoursePriority ON Courses.ID = CoursePriority.CourseID;
其次,我创建了CourseID DurationInDays Priority
1 35 1.000076177
2 21 2.000148297
3 28 3.000094352
4 14 3.000081442
5...
查询:
qryWorkrolePriorityDelay
简单地说:SELECT LnkWorkrolesToCourses.WorkroleID, qryLnkCoursePriorities.CourseID AS CourseID, qryLnkCoursePriorities.Priority, qryLnkCoursePriorities.DurationInDays, ([DurationInDays]+Nz(DSum("DurationInDays","qryLnkCoursePriorities","[Priority]>" & [Priority] & ""))) AS LeadTimeInDays
FROM LnkWorkrolesToCourses INNER JOIN qryLnkCoursePriorities ON LnkWorkrolesToCourses.CourseID = qryLnkCoursePriorities.CourseID
ORDER BY LnkWorkrolesToCourses.WorkroleID, qryLnkCoursePriorities.Priority;
查询告诉我每个课程应提前几天确保新员工可以在所需的培训完成截止日期之前完成所有后续课程。它看起来像这样:
qryWorkrolePriorityDelay
最后,我能够将所有这些结合起来创建WorkroleID CourseID Priority DurationInDays LeadTimeInDays
1 7 1.000060646 7 147
1 1 1.000076177 35 140
1 2 2.000148297 21 105
1 4 3.000081442 14 84
1 6 3.000082824 14 70
1 3 3.000094352 28 56
1 5 4.000106905 28 28
2...
查询:
qryCourseSchedule
此查询为我提供了以下输出:
SELECT Personnel.ID AS PersonnelID, LnkWorkrolesToCourses.CourseID, [ProjectedHireDate]-[leadTimeInDays] AS ProjectedStartDate, [ProjectedHireDate]-[leadTimeInDays]+[Courses].[DurationInDays] AS ProjectedEndDate
FROM Personnel INNER JOIN (((LnkWorkrolesToCourses INNER JOIN (Courses INNER JOIN qryWorkrolePriorityDelay ON Courses.ID = qryWorkrolePriorityDelay.CourseID) ON (Courses.ID = LnkWorkrolesToCourses.CourseID) AND (LnkWorkrolesToCourses.WorkroleID = qryWorkrolePriorityDelay.WorkroleID)) INNER JOIN LnkPersonnelToWorkroles ON LnkWorkrolesToCourses.WorkroleID = LnkPersonnelToWorkroles.WorkroleID) INNER JOIN CoursePriority ON Courses.ID = CoursePriority.CourseID) ON Personnel.ID = LnkPersonnelToWorkroles.PersonnelID
ORDER BY Personnel.ID, [ProjectedHireDate]-[leadTimeInDays]+[Courses].[DurationInDays];
通过此输出,我创建了一个数据透视表,其中课程开始日期按季度分组并计算。这正是我所需要的。