Laravel Eloquent中含子查询的CASE语句实现方案咨询
可行的Eloquent实现方案
方案1:子查询嵌入CASE表达式
先通过Eloquent构造统计关联数据量的子查询,再将其嵌入CASE语句中,用addSelect结合DB::raw实现,既保留Eloquent的可读性,又避免全量Raw SQL:
// 构造子查询:统计当前记录关联的shift_activities数量 $activityCountSubquery = ShiftActivity::selectRaw('count(*)') ->whereColumn('shift_activities.shift_id', 'shifts.id'); // 主查询中添加CASE逻辑列 $reports = Shift::query() ->addSelect([ 'status' => DB::raw(" CASE WHEN ($activityCountSubquery) > 5 THEN '繁忙' WHEN ($activityCountSubquery) BETWEEN 2 AND 5 THEN '正常' ELSE '空闲' END ") ]) ->get();
子查询会被Eloquent自动编译为合法SQL,同时自动处理参数绑定,规避注入风险。
方案2:先定义子查询列,再基于列写CASE
先把关联数据统计结果作为临时列,再基于该列构建CASE逻辑,逻辑拆分更清晰:
$reports = Shift::query() // 新增子查询统计列 ->selectSub( ShiftActivity::selectRaw('count(*)') ->whereColumn('shift_activities.shift_id', 'shifts.id'), 'activity_count' ) // 基于临时列编写CASE ->addSelect([ 'status' => DB::raw(" CASE WHEN activity_count > 5 THEN '繁忙' WHEN activity_count BETWEEN 2 AND 5 THEN '正常' ELSE '空闲' END ") ]) ->get();
方案3:使用Laravel 9+的Case表达式构造器
Laravel 9及以上版本提供了流畅的CaseExpression构造器,无需手写Raw SQL字符串,完全通过Eloquent API构建逻辑:
use Illuminate\Database\Query\Expression\CaseExpression; $activityCountSubquery = ShiftActivity::selectRaw('count(*)') ->whereColumn('shift_activities.shift_id', 'shifts.id'); $caseExpression = CaseExpression::make() ->when(fn($query) => $query->whereRaw("($activityCountSubquery) > 5"), '繁忙') ->when(fn($query) => $query->whereRaw("($activityCountSubquery) BETWEEN 2 AND 5"), '正常') ->else('空闲'); $reports = Shift::query() ->addSelect(['status' => $caseExpression]) ->get();
内容的提问来源于stack exchange,提问作者Cameron Kilgore
相关产品推荐
相关产品推荐

