如何使用Eloquent筛选仅最近预约状态为closed的Patient?
用Eloquent筛选最近一次预约状态为'closed'的患者
方法一:关联子查询直接筛选
先确保你的Patient模型已定义与Appointment的一对多关联:
// app/Models/Patient.php public function appointments() { return $this->hasMany(Appointment::class); }
通过whereHas结合子查询,定位每个患者的最新预约并校验状态:
$patients = Patient::whereHas('appointments', function ($query) { // 子查询获取当前患者的最新预约ID $latestAppointment = Appointment::select('id') ->whereColumn('patient_id', 'patients.id') ->orderByDesc('appointment_date') ->limit(1); $query->where('id', $latestAppointment) ->where('status', 'closed'); })->get();
方法二:定义「最新预约」关联简化查询
在Patient模型中新增关联,直接指向患者的最新预约:
// app/Models/Patient.php public function latestAppointment() { return $this->hasOne(Appointment::class)->latest('appointment_date'); }
后续查询会更简洁,直接通过whereHas检查关联状态:
$patients = Patient::whereHas('latestAppointment', function ($query) { $query->where('status', 'closed'); })->get();
方法三:Join分组实现
若偏好SQL Join逻辑,可通过分组获取每个患者的最新预约后筛选:
use Illuminate\Support\Facades\DB; $patients = Patient::select('patients.*') ->join('appointments', 'patients.id', '=', 'appointments.patient_id') ->whereIn('appointments.id', function ($query) { $query->select('id') ->from('appointments as a') ->whereColumn('a.patient_id', 'appointments.patient_id') ->orderByDesc('a.appointment_date') ->limit(1); }) ->where('appointments.status', 'closed') ->get();
补充:更贴合需求的简化写法
如果你的核心需求是排除所有存在open状态预约的患者,直接用whereDoesntHave逻辑更直接:
$patients = Patient::whereDoesntHave('appointments', function ($query) { $query->where('status', 'open'); })->get();
内容的提问来源于stack exchange,提问作者user3045457
相关产品推荐
相关产品推荐

