如何在Laravel中基于数据透视表对结果进行排序

时间:2018-07-25 05:56:28

标签: laravel laravel-5 orm pivot laravel-orm

我有三个这样的表:

  • 游览(id名称)->假设(id:1,name:某物)
  • 元(id键)->假定(id:1,键:tour_duration)
  • meta_tour(tour_id meta_id值)->假设(tour_id:1,meta_id:1,值15)

这是ManyToMany关系。

我想基于meta_tour表中的元值对游览进行排序:

tours orderBy tour_duration.value

更新

我尝试过这个:

        Tour::with(['metas' => function ($query) {
        $query->where('key', 'tour_duration')
        ->orderByDesc('value');
        }])->paginate(15);

和这个:

        Tour::with(['metas' => function ($query) {
        $query->where('key', 'tour_duration');
        }])->orderByDesc('value')->paginate(15);

这:

        Tour::whereHas('metas' , function ($query) {
        $query->where('key', 'tour_duration')
              ->orderBy('value', 'desc')
        })->paginate(15);

但不起作用。

3 个答案:

答案 0 :(得分:1)

您可以使用withPivot方法按数据透视表列进行排序:

// Tour model
public function meta () {
    return $this->belongsToMany(Meta::class)
                ->withPivot('meta_tour')
                ->orderByDesc('meta_tour.value');
}

更新

要仅获取具有持续时间的元数据,请尝试快速加载并在元数据上添加where子句:

$tour->with(['meta' => function ($query) {
    $query->where('key', 'tour_duration');
}])->orderByDesc('meta.value')->get();

答案 1 :(得分:0)

您可以使用修改后的withCount()

Tour::withCount(['metas as tour_duration' => function ($query) {
    $query->select('meta_tour.value')->where('key', 'tour_duration');
}])->orderByDesc('tour_duration')->paginate(15);

这使用子查询从数据透视表中获取value

select `tours`.*,
  (select `meta_tour`.`value`
   from `metas`
   inner join `meta_tour` on `metas`.`id` = `meta_tour`.`meta_id`
   where `tours`.`id` = `meta_tour`.`tour_id`
     and `key` = 'tour_duration') as `tour_duration`
from `tours`
order by `tour_duration` desc

答案 2 :(得分:0)

尝试:

Tour::join('meta_tour', 'meta_tour.tour_id', '=', 'tour.id')
    ->join('meta', 'meta_tour.meta_id', '=', 'meta.id')
    ->where('meta.key', '=', 'tour_duration')
    ->orderBy('meta_tour.value', 'DESC')
    ->get();