1

我有 4 个学期的学生,我很关心他们每个科目的出勤率。不同学期的学生被分组。每批都可以从 36 个科目中选择一个科目。

首先,我创建了一个表格,subject其中列出了四个批次的所有主题以及主题代码。我有另一个表student,其中有studentid6 个列,其中包含学生选择的主题代码。通过执行连接,我可以知道学生选择了哪个科目。

现在我无法弄清楚如何以干净的方式存储每日出勤率。请提出一种方法,因为我需要存储 365 天和 1500 多名学生的数据。(部分批次周日不放假)。

我发现了一些相关的主题,包括在数据库中存储考勤记录和其他一些主题,但我找不到解决方案。

4

2 回答 2

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
于 2013-02-24T08:55:41.390 回答
0

创建一个连接表,其中包含学生和学科的外键以及日期字段,并为在给定日期参加特定课程的每个学生存储一行。通过适当的索引,性能应该是可以接受的。

于 2013-02-24T08:50:06.210 回答