orderBy 可以按照关联 with 查询里面的字段排序吗?

orderBy 可以按照with 查询里面的字段排序吗? orderBy 如何加子查询喃?

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 14

不可以,那是个子查询

3周前 评论
tiantian10000 (楼主) 3周前
tiantian10000 (楼主) 3周前

orderBy 后面跟子查询是什么意思, orderBy都是在最后执行的了呀

3周前 评论

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 操作之前,故不能使用

3周前 评论
tiantian10000 (楼主) 3周前
荒街! (作者) 3周前

试试查出来后通过each循环,把需要排序的放到第一层,然后用sortBy()

3周前 评论

上面说的不对,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+以上使用, 低版本没有试过

3周前 评论
zhaojjiang 3周前
tiantian10000 (楼主) 3周前
还不出来 (作者) 3周前
zhaojjiang 3周前

巧了,我最近刚好也有同样的需求,然后在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']);
2周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!