【问题标题】:Attendance system using PHP & MySQL使用 PHP & MySQL 的考勤系统
【发布时间】:2017-03-16 17:16:10
【问题描述】:

我在一个使用 PHP 和 MySQL 的模块项目中有一个考勤系统,MySQL 表如下所示:

现在,时间表用于存储一天中某个部分的课程时间表以及分配给它的老师。 student_info 表包含有关学生及其所属部门的一般信息。 考勤表用于记录缺勤,使用时间和学生证作为主键。

我可以计算一个学期有多少课,如下所示:

SELECT count(*) as total FROM timetable WHERE flag > ? AND semester = ? AND section = ? AND timeid BETWEEN ? AND ?

然后计算一个学生参加了多少次,并计算出勤率。

SELECT stu.* , 
    (SELECT COUNT(*) 
    FROM attendancetable    att 
    WHERE att.s_id = stu.class_roll
    AND att.semester = ?
    AND att.timeid BETWEEN ? AND ? ) AS absent
FROM student_info   stu
WHERE stu.section = ?
AND stu.logYear = ?
AND stu.deleted = ?
ORDER BY stu.class_roll

现在,我还想显示一种考勤表,如下所示:

我尝试了 SQL Inner Join,但没有得到我想要的方式。

我在想第一行可以从以下查询中输出:

SELECT timeid 
FROM timetable 
WHERE flag > ? 
  AND semester = ? 
  AND section = ? 
  AND timeid BETWEEN ? AND ?

[UPDATE] 找到了一种方法,作为答案给出,不知道这是否是正确的方法。

提前感谢您的帮助。

【问题讨论】:

  • 是我的问题太模糊还是发生了什么?我没有得到回应或帮助。还是我的初始表格做错了什么?我需要重新设置我的数据库吗?任何人都可以帮忙...
  • 你找到解决办法了吗?我看起来完全一样....
  • @query 还没有。如果我找到了会更新。
  • @query 我确实找到了一些解决方案,请检查并提供 cmets。

标签: php mysql sql


【解决方案1】:

我的回答可能有点晚了,但我也一直在玩,想出了一个主要在 MySql 中完成的解决方案:我的解决方案构建了一个动态的 SELECT 语句,该语句在最后执行为我提供表格,其中包含跨越预定义时代的列:

SET @str='SELECT sid';
SELECT @str:=concat(@str,', MAX(CASE tid WHEN ',t_id,
                    ' THEN \'OK\' ELSE \'\' END) d',t_id) 
--                            start date          end date
FROM times WHERE dati BETWEEN '20170810.0000' and '20171022.2359';
SET @str=concat(@str,' FROM att GROUP BY sid');
PREPARE qu FROM @str;
EXECUTE qu;

仍然需要做的是将列标题中的日期 ID 转换为正确的日期,同样,将学生 ID 转换为姓名或univ_roll 数字。

我还冒昧地稍微更改了表格布局:时间表中的主键现在只是一个整数,实际时间单独存储在另一列中,以便在日期或时间可能发生变化时提供灵活性。

这里有一个小程序演示:http://rextester.com/LPFF99061(仅前几个日期填写了出勤表)。

【讨论】:

  • 俗话说“迟到总比不到好”,感谢分享。您的解决方案似乎更好。我会试试这个。看来我需要更多地了解mysql。
【解决方案2】:

我不确定是否应该使用这些更新来编辑问题。但这是我提出的部分解决方案。如果有人可以帮助优化这一点,我们会很高兴。

所以,我从这段代码开始。

SELECT timeid 
FROM timetable 
WHERE flag > ? 
  AND semester = ? 
  AND section = ? 
  AND timeid BETWEEN ? AND ?

从上面的代码我可以得到上课的日期。接下来,我会检查学生在以下提到的日期是否在场或缺席:

SELECT attended FROM attendancetable
    WHERE s_id = ?
    AND semester = ?
    AND timeid = ?

通过这个,我能够查看学生是否缺席。在 php 中它看起来像这样:

//Getting the dates
$query = "SELECT timeid FROM timetable
        WHERE flag > ?
        AND semester = ?
        AND section = ?
        AND timeid BETWEEN ? AND ?";
$params = array(0, 1, 'A', '2017-01-01', '2017-06-30' );
$stmt = $db->prepare($query);
$stmt->execute($params);
$dates = $stmt->fetchall();

//checking if students is present or absent
$query = "SELECT attended FROM attendancetable
        WHERE s_id = ?
        AND semester = ?
        AND timeid = ?";

//Now I'm going to loop through the $dates
foreach($dates as $date){
    $params = array(1, 'A', $date['timeid']);
    $stmt = $db->prepare($query);
    $stmt->execute($params);
    $result = $stmt->fetchall();
    ($result) ? $present = 1 : $present = 0;
}

通过上述方式,我能够根据时间表计算给定班级的特定部分的学生是否在场/缺席。现在,如果我想要一个部分中的所有学生,我可以首先查询student_info 表,然后为每个学生计算foreach 循环

SELECT class_roll FROM student_info
    WHERE logYear = ?
    AND section = ?
    AND deleted = ? 
    ORDER BY class_roll LIMIT ?, ?

然后每个学生都通过 foreach 循环运行,以检查他们是否缺席或存在。最后,我可以得到这个:

我在本地测试了大约 200 名学生的执行时间,当班级数量只有 39 时,它达到了大约 1.6 秒。我也从以前的数据中测试了一整个学期,代码超过 30 秒,max_execution_time 错误触发。截至目前,我设置了每页 25 名学生的限制。

更新max_execution_time 错误似乎只在第一次运行时出现,但后来当我尝试重新生成它时不再给出错误和时间完成任务的时间不到 2 秒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 2019-03-15
    • 2020-11-11
    • 2021-02-19
    相关资源
    最近更新 更多