2013-05-15 29 views
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和学生证的表格。

一旦我明白了这一点,我想最终建立它并添加更多的方法来将它们分开。

Incase你想知道为什么我想这样做是因为我们目前的调度程序不支持这种调度,我不知道什么时候可以添加它。但即使只是这个简单的步骤,也可以节省大量的时间。

我很欣赏任何输入或帮助。

+4

'我需要他们是性别平衡的.. ..但没有你的设置中的性别信息..? –

+1

性别平衡是性别歧视!如果只有我和其他人注册,并与其余的女性说服,我们被迫纯粹基于我们的生殖器进入不同的课程!我反对:P – Wrikken

+0

对不起,忘了添加有一个字段是为M或F的学生 – Mysteri0n

回答

0

遵循规范化原则并使用您现有的架构, 我猜你所要求的并不是你想要的

我不明白你为什么需要表格中的teacherID,因为你已经有了TeacherID FK的课程表。

我觉得你需要的是一个StudentCourses表。此表将有两个字段,studentID和courseID(courseID作为FK到课程表和studentID到学生表。持学生证和CourseID的两个部分的复合PK。

的样本数据会看起来像

 StudentRegistrations 

    CourseID   StudentID 
    5007010    26352 
    5007010    26732 
    6003790    26352 

这是除非我完全误解了,你只是要求我们写一个SP随机放在课程的学生。不过,我的观点我在上面做仍然站立。

+0

你说得很好。这将工作只是我的课程和学生证。我在sql方面非常精通,但远不是sql master。但我想用存储过程随机询问学生上课,同时在课程中保持性别平衡。我只是不确定如何去做。 – Mysteri0n

+0

@ AcidBurn85 Gotcha,这是一个非常陡峭的要求,因为它没有自己开始,但看起来戈登试图用他的答案来解决它 - 给这个镜头。 – Scotch

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四舍五入到下一个整数,并将其用于估算。这对你的目的可能已经足够了。

而且,此解决方案中的代码是为了说明解决方案。它可能有句法问题。