我有4个学期的学生,我担心他们每个科目的出勤率。不同的学期学生被分成批次。每个批次都可以选择36个科目中的科目。
首先,我创建了一个表subject
,其中列出了四个批次的所有主题和主题代码。我有另一张表student
,其中我有studentid
和6列,其中的主题代码由学生选择。通过执行加入,我可以知道学生选择了哪个科目。
现在我无法弄清楚如何以干净的方式存储每日出勤率。请提出建议,因为我需要存储365天的数据和超过1500名学生。 (周日不是某些批次的假期)。
我发现很少有相关话题,包括Storing attendance records in the database和其他几个,但我找不到解决方案。
答案 0 :(得分:3)
我会有这样的事情:
Subjects( SubjectId PK, Name, etc... )
Classes( ClassId PK, SubjectId, DateTime periodBegin, etc... )
Students( StudentId PK, Name, etc... )
StudentAttendance( StudentId PK, ClassId PK )
Subjects
包含每个主题的记录,Classes
包含学校日历中每个预定课程的记录。 Classes
表需要填充实际的类程序集 - 您可以在它们发生时添加它们,也可以在学年开始时批量添加它们。 Students
表是不言自明的,StudentAttendance
表列出了哪些学生积极参加特定课程。
不要认为像StudentAttendance
这样的表是一个糟糕的设计 - 这是多对多连接表的规范示例。看到一些连接表中有数十亿行的数据库并不罕见,但由于它只包含两个键值(可能是int32或int64),所以它在磁盘上没有占用太多空间。
这是一个查询,查找哪些学生没有参加特定课程:
SELECT
Name
FROM
Students
WHERE
StudentId NOT IN (
SELECT
StudentId
FROM
StudentAttendance
INNER JOIN Classes ON StudentAttendance.ClassId = Classes.ClassId
WHERE
StudentAttendance.ClassId = @classId
)
这是一个查询,可以获得每个参加特定科目的学生的出勤率。将其除以(SELECT Count(*) FROM Clases WHERE Classes.SubjectId = @subject
)以获得每个学生的出勤率。如果学生从未上过任何课程(故意或因为没有注册),那么他们就不会出现在列表中。
SELECT
Students.Name
COUNT(*) As AttendanceCount
FROM
StudentAttendance
INNER JOIN Classes ON Classes.ClassId = StudentAttendance.ClassId
INNER JOIN Students ON Students.StudentId = StudentAttendance.StudentId
GROUP BY
StudentId
WHERE
Classes.SubjectId = @subjectId
答案 1 :(得分:0)
创建一个包含外键的连接表到学生和主题,以及日期字段,并为在给定日期参加特定课程的每个学生存储一行。通过适当的索引,性能应该是可以接受的。