讨论数量:
上面说的不对,orderBy可以根据with关联中的字段来进行排序的,排序的实现是以子查询的方式来的;数据量一大就会比较慢,不建议这么使用;如果不考虑性能,写法真的非常方便简洁;
直接贴代码,首先注册Illuminate\Database\Eloquent\Builder
宏
Builder::macro('orderByWith', function ($relation, $column, $direction = 'asc'){
/** @var Builder $this */
if (is_string($relation)) {
$relation = $this->getRelationWithoutConstraints($relation);
}
return $this->orderBy(
$relation->getRelationExistenceQuery(
$relation->getRelated()->newQueryWithoutRelationships(),
$this,
$column
),
$direction
);
});
然后就可以直接使用了
// 查询用户列表,根据订单关联的价格字段进行倒排
User::where(...)->orderByWith('orders','price','desc')->get();
PS:laravel7+以上使用, 低版本没有试过
with
实际上是执行了两条 sql
,第一条 sql
执行完之后,根据第一次查询出的结果,通过 IN
获取 with
内关联的表数据
User::with('article')->where('id', '>', 10)->orderByDesc('id')->get();
// 实际执行两条 sql
// SELECT * FROM user WHERE id > 10 ORDER BY id DESC;
// SELECT * FROM article WHERE user_id IN(13,12,11); -- 这里的 user_id 是模型指定的关联字段,in内的字段为上一条 sql 查出的内容
综上所述,orderBy
是在执行 with
操作之前,故不能使用
上面说的不对,orderBy可以根据with关联中的字段来进行排序的,排序的实现是以子查询的方式来的;数据量一大就会比较慢,不建议这么使用;如果不考虑性能,写法真的非常方便简洁;
直接贴代码,首先注册Illuminate\Database\Eloquent\Builder
宏
Builder::macro('orderByWith', function ($relation, $column, $direction = 'asc'){
/** @var Builder $this */
if (is_string($relation)) {
$relation = $this->getRelationWithoutConstraints($relation);
}
return $this->orderBy(
$relation->getRelationExistenceQuery(
$relation->getRelated()->newQueryWithoutRelationships(),
$this,
$column
),
$direction
);
});
然后就可以直接使用了
// 查询用户列表,根据订单关联的价格字段进行倒排
User::where(...)->orderByWith('orders','price','desc')->get();
PS:laravel7+以上使用, 低版本没有试过
巧了,我最近刚好也有同样的需求,然后在stackoverflow上找了到一个方法,亲测有效
// 两张表,一张 elevators 一张 elevators_extras
// elevators_extras.elevator_id和elevators.id关联
// 检索elevators根据elevator_extras.is_urgent排序
$listData = Elevator::with(['extra'])
->orderBy(ElevatorExtra::select('is_urgent')->whereColumn('elevator_extras.elevator_id', 'elevators.id'), 'desc')
->paginate($form['pageSize']);
推荐文章: