如何按 Laravel 中的预加载结果排序?
How to sort by eager loading results in Laravel?
我对预加载非常陌生,运行 遇到了我认为是我只是不理解的简单问题。我查看了一些 the materials here 并环顾四周,但似乎无法找到我所问内容的正确术语。
目前我的装备模型有如下关系:
public function registrationsExpireLatest()
{
return $this->hasOne(EquipmentLicense::class,'equipmentID','id')
->orderByDesc('expirationDate');
}
这非常有效,但是假设我想将它放在 @foreach 下的索引 blade 上,我得到了我需要的一切,包括使用以下代码的到期日期:
@foreach ($equipments as $equipment)
<tr>
<td><a href="/origins/{{$equipment['id']}}">{{$equipment['unit_id']}}</a></td>
<td>{{\Crypt::decryptString($equipment->licensePlate)}}</td>
<td>@if (count($equipment->registrationsExpireLatest))
{{$equipment->registrationsExpireLatest->expirationDate}}
@endif</td>
</tr>
@endforeach
来自这个控制器代码:
$equipments = Equipment::with(['registrationsExpireLatest' => function ($query) {
$query->orderBy('expirationDate', 'asc');
}])
->where([
['unit_type','<',3],
['active','=',1]
])
->limit(10)
->get();
所有输出都是这样的:
11 086-YRR 2015-05-31
26 062-XWE 2018-11-30
33 880-HNV 2018-04-30
39 820-YYT 2018-01-31
203 279-WWU 2013-12-31
31 BMR 199 2018-04-30
UNK3 997-WLH 2011-09-30
1 957-VDN 2018-05-31
1096 187-MFF 2015-01-31
2105 154-CLU 2018-01-31
正如您在我的控制器上看到的那样,我已经尝试按照我认为正确的方式进行排序:https://laravel.com/docs/5.3/eloquent-relationships#constraining-eager-loads
但是正如您从我的结果中看到的那样table,它们根据到期日期是乱序的。
我希望它按日期提前(如 2011 年)和晚些(如 2018 年)。有办法吗?
您当前正在对相关集合进行排序,即如果 registrationsExpireLatest
是一个 one-to-many 关系,则相关模型将按其 expirationDate
升序排序你们每个 Equipments
。据我从你的模型可以看出,你已经加入了最新的实体。
要对关系上的 Equipments
进行排序通常并不难,您只需加入相关的 table。但是在您的情况下,如果每个 Equipment
的相关 table 中有多个元素,连接会稍微复杂一些。我认为类似以下的方法可行:
Equipment::where([
['unit_type','<',3],
['active','=',1]
])
->join(DB::raw('(SELECT equipmentID, MAX(expirationDate) AS latest FROM equipment_license GROUP BY equipmentID) AS tmp'), 'equipment.id', '=', 'tmp.equipmentID')
->orderBy('tmp.latest')
->select('equipment.*', 'tmp.latest')
->limit(10)
->get();
(基于)
JOIN 需要一个别名:
Equipment::where([
['unit_type','<',3],
['active','=',1]
])
->join(DB::raw('(SELECT equipmentID, MAX(expirationDate) AS latest FROM equipment_license GROUP BY equipmentID) as license'), 'equipment.id', '=', 'license.equipmentID')
->orderBy('license.latest')
->limit(10)
->get();
我对预加载非常陌生,运行 遇到了我认为是我只是不理解的简单问题。我查看了一些 the materials here 并环顾四周,但似乎无法找到我所问内容的正确术语。
目前我的装备模型有如下关系:
public function registrationsExpireLatest()
{
return $this->hasOne(EquipmentLicense::class,'equipmentID','id')
->orderByDesc('expirationDate');
}
这非常有效,但是假设我想将它放在 @foreach 下的索引 blade 上,我得到了我需要的一切,包括使用以下代码的到期日期:
@foreach ($equipments as $equipment)
<tr>
<td><a href="/origins/{{$equipment['id']}}">{{$equipment['unit_id']}}</a></td>
<td>{{\Crypt::decryptString($equipment->licensePlate)}}</td>
<td>@if (count($equipment->registrationsExpireLatest))
{{$equipment->registrationsExpireLatest->expirationDate}}
@endif</td>
</tr>
@endforeach
来自这个控制器代码:
$equipments = Equipment::with(['registrationsExpireLatest' => function ($query) {
$query->orderBy('expirationDate', 'asc');
}])
->where([
['unit_type','<',3],
['active','=',1]
])
->limit(10)
->get();
所有输出都是这样的:
11 086-YRR 2015-05-31
26 062-XWE 2018-11-30
33 880-HNV 2018-04-30
39 820-YYT 2018-01-31
203 279-WWU 2013-12-31
31 BMR 199 2018-04-30
UNK3 997-WLH 2011-09-30
1 957-VDN 2018-05-31
1096 187-MFF 2015-01-31
2105 154-CLU 2018-01-31
正如您在我的控制器上看到的那样,我已经尝试按照我认为正确的方式进行排序:https://laravel.com/docs/5.3/eloquent-relationships#constraining-eager-loads
但是正如您从我的结果中看到的那样table,它们根据到期日期是乱序的。
我希望它按日期提前(如 2011 年)和晚些(如 2018 年)。有办法吗?
您当前正在对相关集合进行排序,即如果 registrationsExpireLatest
是一个 one-to-many 关系,则相关模型将按其 expirationDate
升序排序你们每个 Equipments
。据我从你的模型可以看出,你已经加入了最新的实体。
要对关系上的 Equipments
进行排序通常并不难,您只需加入相关的 table。但是在您的情况下,如果每个 Equipment
的相关 table 中有多个元素,连接会稍微复杂一些。我认为类似以下的方法可行:
Equipment::where([
['unit_type','<',3],
['active','=',1]
])
->join(DB::raw('(SELECT equipmentID, MAX(expirationDate) AS latest FROM equipment_license GROUP BY equipmentID) AS tmp'), 'equipment.id', '=', 'tmp.equipmentID')
->orderBy('tmp.latest')
->select('equipment.*', 'tmp.latest')
->limit(10)
->get();
(基于
JOIN 需要一个别名:
Equipment::where([
['unit_type','<',3],
['active','=',1]
])
->join(DB::raw('(SELECT equipmentID, MAX(expirationDate) AS latest FROM equipment_license GROUP BY equipmentID) as license'), 'equipment.id', '=', 'license.equipmentID')
->orderBy('license.latest')
->limit(10)
->get();