我必须对数据库进行一次查询,这会返回很多行(第1行)。我希望我只能进行一次此查询,然后在其上应用各种过滤器,而无需再次访问数据库。像这样:
$finishedTrips = Auth::user()->trips()->whereNotNull('distance');
$transport = Config::get('transport');
foreach($transport as $key => $value) {
$sum = $finishedTrips->where('transport', '=', $value['id'])->sum('distance');
}
这不行,我花了一个小时意识到我确实需要这样做才能让它运转起来:
$transport = Config::get('transport');
foreach($transport as $key => $value) {
$sum = Auth::user()->trips()->whereNotNull('distance')->where('transport', '=', $value['id'])->sum('distance');
}
但我现在有四个可能很重的查询而不是一个。有没有办法解决我的第一个例子?我应该使用缓存吗?
答案 0 :(得分:0)
是的,可以只进行一次查询以获取所有结果,然后过滤结果。
$finishedTrips = Auth::user()->trips()->whereNotNull('distance')->get();
现在$finishedTrips
是Illuminate/Database/Eloquent/Collection的一个实例,其中有一个方法filter()可用于过滤结果
$transports = Config::get('transport');
foreach($transports as $transport) {
$filteredList = $finishedTrips->filter(function ($t) use($transport) {
return $t->transport == $transport['id'];
});
$sum = array_sum($filteredList->lists('distance'));
}
但这是一个非常糟糕的方法。您应该使用的是一个单独的查询,按transport
进行分组并汇总distance
。
// Code not tested but you get the idea
Trips::where('user_id', Auth::user()->id)->groupBy('transport')->sum('distance');
只需一行代码即可实现相同目的。