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

Laravel中列值为数组时如何关联两张表并获取目标报告

Laravel中数组列的表关联与筛选包含全部指定参与者的报告

一、数组列的表关联实现

如果你的reports表中participants列存储的是用户ID的JSON数组(如[1,2,3]),由于不符合传统数据库范式,无法直接使用Laravel默认关联方法,可通过自定义逻辑实现关联:

在Report模型中配置关联

// app/Models/Report.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\User;

class Report extends Model
{
    // 自动将JSON列转为PHP数组
    protected $casts = [
        'participants' => 'array',
    ];

    // 获取报告对应的参与者用户集合
    public function participants()
    {
        return User::whereIn('id', $this->participants)->get();
    }

    // 或者用访问器实现动态属性
    public function getParticipantsUsersAttribute()
    {
        return User::whereIn('id', $this->participants)->get();
    }
}

调用示例:

$report = Report::find(1);
// 获取该报告的所有参与者用户
$users = $report->participants();
// 或通过访问器获取
$users = $report->participants_users;

二、筛选包含全部指定参与者的报告

要查询participants列包含所有指定用户ID的报告,可利用数据库JSON函数(以MySQL为例):

示例代码

// 指定必须包含的用户ID数组
$requiredUserIds = [2, 3];

// 查询符合条件的报告
$reports = \App\Models\Report::whereRaw(
    'JSON_CONTAINS_ALL(participants, ?)',
    [json_encode($requiredUserIds)]
)->get();

特殊情况处理

如果participants列是序列化字符串存储的数组(如a:2:{i:0;i:2;i:1;i:3;}),这种方式不推荐,建议迁移为JSON类型;若无法修改结构,可通过多条件like查询(效率较低):

$reports = Report::query();
foreach ($requiredUserIds as $id) {
    $reports->where('participants', 'like', "%\"{$id}\"%");
}
$reports = $reports->get();

更优方案:改用多对多关联

直接存储数组违背数据库设计范式,会导致查询低效、维护困难。建议新增中间表report_user,结构如下:

字段名类型
report_idunsigned int
user_idunsigned int

然后在Report模型中定义标准多对多关联:

public function participants()
{
    return $this->belongsToMany(User::class, 'report_user');
}

筛选包含全部指定用户的报告时,使用whereHas:

$requiredUserIds = [2, 3];
$reports = Report::whereHas('participants', function ($query) use ($requiredUserIds) {
    $query->whereIn('id', $requiredUserIds);
}, '=', count($requiredUserIds))->get();

内容的提问来源于stack exchange,提问作者user7039160

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:25:17