You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 11:10:41