Laravel Eloquent关联查询:如何在子查询中使用数据库记录字段?
Laravel Eloquent关联子查询中使用关联记录字段的实现方法
你原来的写法存在两个核心问题:一是在with的闭包里调用$query->first()会提前执行额外查询,获取的并非当前父模型关联的对应记录;二是这种方式无法针对每个Client的关联records动态应用基于duration字段的条件,必须让数据库层面处理这个动态计算的逻辑。
下面是两种可行的实现方式:
方式一:使用whereRaw直接编写SQL条件
这种方式直接用原生SQL表达式实现动态计算的时间条件,让数据库自动关联当前record的duration字段:
use Illuminate\Database\Eloquent\Builder; use Carbon\Carbon; $clients = Client::with(['records' => function (Builder $query) { // 示例逻辑:筛选time >= 当前时间减去(10 + duration)分钟的记录,可根据需求调整运算符 $query->whereRaw('time >= DATE_SUB(NOW(), INTERVAL (10 + duration) MINUTE)'); }])->where('profile_id', $profile->id)->get();
方式二:使用DB::raw结合Eloquent的where方法
这种方式更贴合Eloquent的语法风格,同样由数据库处理动态字段计算:
use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\DB; use Carbon\Carbon; $clients = Client::with(['records' => function (Builder $query) { $query->where('time', '>=', DB::raw('DATE_SUB(NOW(), INTERVAL (10 + duration) MINUTE)')); }])->where('profile_id', $profile->id)->get();
关键说明
- 不要在
with的关联查询闭包里提前执行first()或get(),这会打断关联查询的上下文,无法针对每个父模型(Client)的关联记录动态应用条件。 - 上述代码的时间逻辑为
time >= 当前时间减去(10 + duration)分钟,如果你的需求是筛选更早或更晚的记录,只需调整运算符(比如改成<=)即可。
内容的提问来源于stack exchange,提问作者Александр Жуков
相关产品推荐
相关产品推荐

