考勤数据处理异常求助:日期重复、上下班时间分配错误
解决考勤记录合并与字段填充问题
看起来你的代码里有两个关键问题导致了当前的错误:条件判断用了赋值运算符而非比较运算符,以及没有按员工+日期合并考勤记录。咱们一步步来修复:
问题根源分析
- 条件判断的运算符错误:你在
if判断里用了=(赋值)而不是==(比较),比如if($row->status='C/Out'),这会把$row->status强制设为C/Out,并且这个表达式永远返回真,导致你的时间填充逻辑完全混乱。 - 未合并同一日期的记录:你现在是逐条插入原始数据,所以同一个员工同一天的C/In和C/Out会被分成两条记录插入,自然出现日期重复,且两个字段无法正确对应。
修复后的代码实现
我们先把原始数据按「员工ID+日期」分组,收集同一天的上班和下班时间,再统一插入合并后的记录:
public function processTimesheet(){ $this->load->model('dbquery'); // 先查询所有原始考勤数据 $query = $this->db->query("SELECT * FROM tbldumpbio"); // 用数组按员工ID+日期分组存储考勤信息 $attendanceData = []; foreach ($query->result() as $row){ $dateTimeExplArr = explode(' ', $row->datetimex); $dateStr = $dateTimeExplArr[0]; $timeStr = $dateTimeExplArr[1] ?? ''; // 用null合并运算符处理空时间 // 生成唯一键:员工ID+日期,确保同一员工同一天的记录归为一组 $key = $row->empid . '_' . $dateStr; // 初始化分组数据(如果不存在的话) if (!isset($attendanceData[$key])) { $attendanceData[$key] = [ 'name' => $row->name, 'empCompID' => $row->empid, 'date' => $dateStr, 'timeIn' => '', 'timeOut' => '' ]; } // 正确判断状态并填充对应时间(注意用==比较) if ($row->status == 'C/In' && !empty($timeStr)) { $attendanceData[$key]['timeIn'] = $timeStr; } elseif ($row->status == 'C/Out' && !empty($timeStr)) { $attendanceData[$key]['timeOut'] = $timeStr; } } // 遍历分组后的数组,插入合并后的记录 foreach ($attendanceData as $data) { // 补充其他默认字段 $insertData = array_merge($data, [ 'ID' => '', 'companyAccessID' => '', 'status' => '', 'inputType' => '' ]); $this->dbquery->modInsertval('tblempbioupload', $insertData); } }
关键改进点说明
- 修正运算符错误:把
=改成==,确保是比较状态而非赋值。 - 分组存储数据:用
员工ID+日期作为唯一键,把同一天的C/In和C/Out时间合并到同一个数组元素里,避免重复记录。 - 安全处理空时间:用
?? ''(PHP7+支持)处理可能不存在的时间字段,避免isset判断的冗余。 - 统一插入合并记录:最后只插入每组的一条记录,确保同一日期只有一条考勤记录,且timeIn和timeOut字段正确填充。
额外优化建议
如果你的tbldumpbio表数据量很大,建议直接在SQL查询时就按员工和日期分组,用聚合函数获取对应的In/Out时间,这样效率更高:
SELECT empid, name, DATE(datetimex) as date_str, MAX(CASE WHEN status = 'C/In' THEN TIME(datetimex) END) as time_in, MAX(CASE WHEN status = 'C/Out' THEN TIME(datetimex) END) as time_out FROM tbldumpbio GROUP BY empid, name, DATE(datetimex)
然后直接用这个查询结果来插入,省去PHP里的分组逻辑,性能会更好。
内容的提问来源于stack exchange,提问作者zeus2026
相关产品推荐
相关产品推荐

