1

我想构建一个计划程序(我想编写 sql 来执行它,然后我将构建一个 php 站点来执行它)。首先,我想将我学校的学生分配给老师。我需要他们保持性别平衡,这意味着每个班级中一个性别的比例不超过另一个性别的 30%。

所以我有一个包含所有年级 1-5 的学生表和一个教师表,其中包含一个指定他们所教年级的字段。然后我有一个课程表,其中包含每个老师教授的课程,它包含一个具有班级人数限制(仅允许 18 名学生等)的字段以及教授课程的教师 ID。

Student Table Example:

Student_ID  Grade_Level
253486           1
365896           2
485785           3
968654           4
154278           5



Teacher Table Example:

Teacher_ID  Grade Taught
253              1
584              2
985              3
647              4
254              5

Course Table Example:

Course_ID   Class_Limit Teacher_ID
5007010      15            253
5007011      15            584
5007012      18            985
5007013      18            647
5007014      10            254

我想要的最终结果是将记录转储到一个包含三个字段的表中,教师 ID、课程 ID 和学生 ID。

一旦我弄清楚了这一点,我想最终建立在它之上并添加更多的方法来划分它们。

如果您想知道我为什么要这样做是因为我们当前的调度程序不支持这种调度,我不确定他们何时会添加它,如果有的话。但是,即使只是这个简单的步骤,目前也可以节省大量时间。

我感谢任何输入或帮助。

4

2 回答 2

1

这是您可以采取的方法。

关键思想是计算每个班级的男女学生人数,然后分配他们。任务很简单,如果我们有信息的话。所以,假设我们有它:

with magictable (
      <subquery here is nummale and numfemale in each class
     ),
     classinfo (
      select mt.*,
             sum(nummales) over (partition by grade) - 1 as endrange_male,
             sum(nummales) over (partition by grade) - nummales as startrange_male,
             sum(numfemales) over (partition by grade) - 1 as endrange_female,
             sum(numfemales) over (partition by grade) - numfemales as startrange_female
      from magictable mt
     )
select
from (select s.*,
             ROW_NUMBER() over (partition by grade, gender order by student_id) as seqnum
      from student s
     ) s join
     classinfo ci
     on (s.gender = 'M' and s.seqnum between startrange_male and endrange_male) or
        (s.gender = 'F' and s.seqnum between startrange_female and endrange_female)

因此,这将作业信息转化为计算每个班级有多少男性和女性。你可能还有其他方法可以做到这一点,所以我在这里给出一个大概的答案。

可以统计每个年级的学生人数,男生人数,女生人数。通过从总容量中减去实际学生人数来计算“超额”学生人数。这给出了每个类的实际大小。然后按男女比例划分。

以下查询显示了如何执行此操作:

  select c.*,
         (c.class_limit - ((csum.maxcapacity - ssum.numstudents)/csum.numcourses)) as actsize,
         (c.class_limit - ((csum.maxcapacity - ssum.numstudents)/csum.numcourses)) * (NumMales / NumStudents) as actMales,
         (c.class_limit - ((csum.maxcapacity - ssum.numstudents)/csum.numcourses)) * (NumFemales / NumStudents) as actFemales
  from course c join
       teacher t
       on c.teacher_id = t.teacher_id
       (select grade, count(*) as numcourses, SUM(class_limit) as maxcapacity
        from course c join
             teacher t
             on c.teacher_id = t.teacher_id
        group by grade
       ) csum
       on t.grade = csum.grade join
       (select grade, sum(case when gender = 'M' then 1 else 0 end) as NumMales,
               sum(case when gender = 'F' then 1 else 0 end) as NumFemales,
               count(*) as NumStudents
        from s
        group by grade
       ) ssum
       on t.grade = ssum.grade;

问题是,这是一个近似值,因为它涉及分数学生。而且,唉,真正的学生只有非分数大小。

有一个真正的解决方案来计算离散大小。不过,我只是将 NumMales 和 NumFemales 舍入到下一个整数,然后将其用于估计。这对于您的目的可能已经足够了。

并且,此解决方案中的代码用于说明解决方案。它可能有语法问题。

于 2013-05-15T21:46:36.957 回答
0

遵循规范化原则并使用您现有的模式,我猜您所要求的并不是您真正想要的。

我不明白为什么您需要在表中使用teacherID,因为您已经有一个带有 TeacherID FK 的课程表。

我想你需要的是一张StudentCourses桌子。该表将有两个字段,studentID 和 courseID(courseID 是对 Course 表的 FK,对 Student 表的 studentID。具有 Student ID 和 CourseID 的两部分复合 PK。

样本数据看起来像

      StudentRegistrations

    CourseID            StudentID
   5007010                26352
   5007010                26732
   6003790                26352

除非我完全误解了,而你只是要求我们写一个 SP 来随机安排学生上课。尽管如此,我在上面提出的观点仍然成立。

于 2013-05-15T20:03:39.580 回答