Laravel Eloquent按关联模型最小值排序航班的实现方法
按关联Term的最低价格排序Flights的实现方案
针对你的需求,我整理了几种不同的实现方式,从高效的数据库层面查询到备选的集合排序方案,你可以根据自己的Laravel版本和数据规模来选择:
1. 推荐:用Laravel自带的withMin方法(Laravel 8+)
如果你的Laravel版本是8或更高,框架已经提供了非常便捷的withMin方法,能直接在查询时计算关联模型的最小值,再基于这个值排序:
$flights = Flight::withMin('terms', 'price') // 处理没有关联Term的航班,用COALESCE把null转为0,保证排序逻辑一致 ->orderByRaw('COALESCE(terms_min_price, 0)') ->get();
这个方法会自动给每个Flight添加terms_min_price字段,存储对应的最低Term价格,全程在数据库层面完成计算和排序,性能是最优的。
2. 旧版本Laravel:子查询实现
如果你的Laravel版本低于8,可以通过子查询来计算每个Flight的最低价格,再进行排序:
$flights = Flight::select('flights.*') ->selectSub(function ($query) { // 子查询获取当前Flight的最低Term价格,无关联时返回0 $query->selectRaw('COALESCE(MIN(price), 0)') ->from('terms') ->whereColumn('terms.flight_id', 'flights.id'); }, 'min_price') ->orderBy('min_price') ->get();
也可以用左连接+分组的方式实现:
$flights = Flight::leftJoin('terms', 'flights.id', '=', 'terms.flight_id') ->groupBy('flights.id') ->selectRaw('flights.*, COALESCE(MIN(terms.price), 0) as min_price') ->orderBy('min_price') ->get();
这两种方式同样是在数据库层面完成操作,性能比集合排序好很多,适合数据量较大的场景。
3. 备选:集合层面排序(仅小数据量适用)
如果你的数据规模很小,也可以先查询所有Flight及其关联的Term,再在PHP集合中排序:
// 预加载terms关联,避免N+1查询问题 $flights = Flight::with('terms')->get() // 调用你已定义的termMinPrice方法完成排序 ->sortBy('termMinPrice');
⚠️ 注意:这种方式会把所有Flight数据加载到内存后再排序,数据量大时会严重影响性能,只适合小规模数据场景。
内容的提问来源于stack exchange,提问作者DominikN.
相关产品推荐
相关产品推荐

