根据两个站点查询班次,用 Eloquent 可以实现吗

有三张表,1.班次表 2.站点表 3.班次和站点的中间表

schedule
    id - integer
    name - string

point
    id - integer
    name - string

schedule_point
    schedule_id - integer
    point_id - integer
    sort - integer

中间表sort字段排序,区分站点先后顺序
现在要做查询,前端传start_point_id、end_point_id。
start_point中间表的sort必须小于end_point
用laravel优雅的方式可实现吗?

不优雅的做法:

        $a = DB::select('SELECT * FROM schedule WHERE id IN (
            SELECT a.schedule_id FROM
            ( SELECT schedule_id, sort FROM schedule_point WHERE point_id = ? ) AS a,
            ( SELECT schedule_id, sort FROM schedule_point WHERE point_id = ? ) AS b 
            WHERE
                a.schedule_id = b.schedule_id 
            AND a.sort < b.sort 
            )',[140,141]);
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案
$sql = SchedulePoint::whereIn('id', function (Builder $query) {
            $query->select('schedule_id')
                ->from(function (\Illuminate\Database\Query\Builder $query) {
                        $query->select('a.schedule_id ')
                            ->from(function ($query){
                                $query->select('schedule_id', 'sort')
                                    ->from('schedule_point','a')
                                    ->where('point_id', 140);
                                },'a'
                            )
                            ->joinWhere('schedule_point as b','point_id', '=',141)
                            ->whereColumn('a.schedule_id', 'b.schedule_id')
                            ->whereColumn('a.sort', '<', 'b.sort');
                },'c');
        })->toSql();
//输出结果如下
select * from `schedule_point` where `id` in (select `schedule_id` from (select `a`.`schedule_id ` from (select `schedule_id`, `sort` from `schedule_point` where `point_id` = ?) as `a` inner join `schedule_point` as `b` on `point_id` = ? where `a`.`schedule_id` = `b`.`schedule_id` and `a`.`sort` < `b`.`sort`) as `c`)
应该是你想要的,你可以试一试
3年前 评论
讨论数量: 3

可以实现,参考 Eloquent 的多对多关联 模型关联《Laravel 7 中文文档》

3年前 评论
YunMai (楼主) 3年前

这种多对多模型反而是容易实现mysql排序,因为它们是在一条语句里,那么你在排序时指定表名加上字段名即可排序,如

orderBy('schedule_point.sort', 'DESC OR ASC')
3年前 评论
$sql = SchedulePoint::whereIn('id', function (Builder $query) {
            $query->select('schedule_id')
                ->from(function (\Illuminate\Database\Query\Builder $query) {
                        $query->select('a.schedule_id ')
                            ->from(function ($query){
                                $query->select('schedule_id', 'sort')
                                    ->from('schedule_point','a')
                                    ->where('point_id', 140);
                                },'a'
                            )
                            ->joinWhere('schedule_point as b','point_id', '=',141)
                            ->whereColumn('a.schedule_id', 'b.schedule_id')
                            ->whereColumn('a.sort', '<', 'b.sort');
                },'c');
        })->toSql();
//输出结果如下
select * from `schedule_point` where `id` in (select `schedule_id` from (select `a`.`schedule_id ` from (select `schedule_id`, `sort` from `schedule_point` where `point_id` = ?) as `a` inner join `schedule_point` as `b` on `point_id` = ? where `a`.`schedule_id` = `b`.`schedule_id` and `a`.`sort` < `b`.`sort`) as `c`)
应该是你想要的,你可以试一试
3年前 评论

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