如何用Eloquent按关联表字符串字段排序?附Query Builder实现示例
正确的Eloquent实现方案
原Query Builder代码逻辑是左联courts表,按supreme court→high court→area court的固定顺序,以courts.court字段对cases数据排序:
DB::table('cases') ->select('cases.*', DB::raw('courts.*')) ->leftjoin('Courts', 'cases.court_id', '=', 'Courts.id') ->orderByRaw("FIELD(court, 'supreme court','high court','area court')") ->get();
你尝试的代码存在两个核心问题:一是with('courts')属于关联预加载,不会生成JOIN语句,而是单独查询关联数据,无法通过子查询实现基于关联表字段的排序;二是排序字符串的顺序和原需求相反。
以下是几种正确的Eloquent实现方式:
方式一:直接复用JOIN逻辑(与原Query Builder最匹配)
用Eloquent模型替代DB::table(),保留原有的JOIN和排序逻辑,适合需要同时获取两张表所有字段的场景:
return Cases::select('cases.*', 'courts.*') ->leftJoin('courts', 'cases.court_id', '=', 'courts.id') ->orderByRaw("FIELD(courts.court, 'supreme court','high court','area court')") ->get();
注意:确保
Cases模型对应cases表,Court模型对应courts表(Laravel默认模型名单数、表名复数),表名统一小写更规范。
方式二:JOIN+关联预加载(保留Eloquent关联特性)
如果需要在返回的Cases模型中直接调用关联的court数据,可结合with()和join(),同时避免字段重复:
// 先确保Cases模型中定义关联方法 // public function court() // { // return $this->belongsTo(Court::class); // } return Cases::with('court') ->leftJoin('courts', 'cases.court_id', '=', 'courts.id') ->orderByRaw("FIELD(courts.court, 'supreme court','high court','area court')") ->select('cases.*') // 只查询cases表字段,关联数据由with()加载 ->get();
方式三:子查询排序(无需JOIN)
如果不想使用JOIN,可通过子查询获取排序权重值,实现基于关联表字段的排序:
return Cases::with('court') ->orderByRaw("(SELECT FIELD(court, 'supreme court','high court','area court') FROM courts WHERE id = cases.court_id)") ->get();
内容的提问来源于stack exchange,提问作者Eaimie
相关产品推荐
相关产品推荐

