Laravel中创建嵌套stdClass对象并去除关联查询重复结果
解决Laravel多表Join查询考勤数据重复问题
问题说明
使用Laravel多表Join查询考勤数据时,数据库实际仅存3条用户记录,但查询返回9条重复的stdClass对象。尝试toString()和array_unique()去重无效,希望通过创建嵌套stdClass对象的方式解决重复问题。
原查询代码
$attendance = DB::table('attendances') ->join('users', 'attendances.user_id', '=', 'users.id') ->join('subjects', 'attendances.subject_id', '=', 'subjects.id') ->where('attendances.subject_id', '=', $ideas[0]) ->whereBetween('attendances.date', array($dateFrom, $dateTo)) ->join('class_studs', 'attendances.class_stud_id', '=', 'class_studs.id') ->select('attendances.status','attendances.date','attendances.leave','users.firstname','users.admissionNo','subjects.name', 'class_studs.semester','class_studs.department','class_studs.session') ->get();
查询返回结果
[0] => stdClass Object ( [status] => P [date] => 10/02/2022 [leave] => [firstname] => testing [admissionNo] => 0059 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 ) [1] => stdClass Object ( [status] => P [date] => 10/02/2022 [leave] => [firstname] => arsalan [admissionNo] => 0056 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 ) [2] => stdClass Object ( [status] => P [date] => 10/02/2022 [leave] => [firstname] => khan [admissionNo] => 004 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 ) [3] => stdClass Object ( [status] => P [date] => 10/03/2022 [leave] => [firstname] => testing [admissionNo] => 0059 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 ) [4] => stdClass Object ( [status] => L [date] => 10/03/2022 [leave] => L [firstname] => arsalan [admissionNo] => 0056 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 ) [5] => stdClass Object ( [status] => A [date] => 10/03/2022 [leave] => [firstname] => khan [admissionNo] => 004 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 ) [6] => stdClass Object ( [status] => P [date] => 10/04/2022 [leave] => [firstname] => testing [admissionNo] => 0059 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 ) [7] => stdClass Object ( [status] => P [date] => 10/04/2022 [leave] => [firstname] => arsalan [admissionNo] => 0056 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 ) [8] => stdClass Object ( [status] => P [date] => 10/04/2022 [leave] => [firstname] => khan [admissionNo] => 004 [name] => Data Science [semester] => 6th [department] => computer Science [session] => 2019-2023 )
嵌套对象去重解决方案
通过按用户唯一标识分组,将用户的基础信息与多条考勤记录嵌套整合,自动去除用户维度的重复数据:
// 获取原始查询结果 $rawAttendances = DB::table('attendances') ->join('users', 'attendances.user_id', '=', 'users.id') ->join('subjects', 'attendances.subject_id', '=', 'subjects.id') ->where('attendances.subject_id', '=', $ideas[0]) ->whereBetween('attendances.date', array($dateFrom, $dateTo)) ->join('class_studs', 'attendances.class_stud_id', '=', 'class_studs.id') ->select('attendances.status','attendances.date','attendances.leave','users.firstname','users.admissionNo','subjects.name', 'class_studs.semester','class_studs.department','class_studs.session') ->get(); // 构建嵌套结构的stdClass对象 $groupedAttendances = []; foreach ($rawAttendances as $item) { // 用用户学号作为唯一分组标识 $key = $item->admissionNo; if (!isset($groupedAttendances[$key])) { // 初始化用户基础信息对象 $userObj = new stdClass(); $userObj->firstname = $item->firstname; $userObj->admissionNo = $item->admissionNo; $userObj->subject = $item->name; $userObj->semester = $item->semester; $userObj->department = $item->department; $userObj->session = $item->session; $userObj->attendances = []; $groupedAttendances[$key] = $userObj; } // 创建单条考勤记录对象并嵌套到用户对象中 $attendanceObj = new stdClass(); $attendanceObj->status = $item->status; $attendanceObj->date = $item->date; $attendanceObj->leave = $item->leave; $groupedAttendances[$key]->attendances[] = $attendanceObj; } // 转换为有序的对象数组(可选,根据业务需求调整) $finalAttendances = array_values($groupedAttendances);
最终效果
$finalAttendances将包含3个用户对象,每个对象下嵌套该用户的所有考勤记录,既解决了重复问题,也让数据结构更清晰,便于后续业务处理或前端渲染。
内容的提问来源于stack exchange,提问作者Arsalan Khan
相关产品推荐
相关产品推荐

