我有一个名为gk
的表,目前正在运行两个查询。请查看以下问题:
Gk::groupBy(DB::raw("MONTH(created_at)"))
->groupBy(DB::raw("YEAR(created_at)"))
->selectRaw('id, user_id, sum(ton) as ton,pl, count(id) as total, sum(w) , created_at')
->with(array('user'=> function($q){
$q->select('id', 'userName', 'profilePic');
}))
->where('user_id', $userData[0]->id)
->get();
此查询返回每个月的一点摘要。正如你所看到的,我正在按月份和年份对结果进行分组。我还有一个查询,它将返回任何给定月份的所有行。
我正在运行这样的第二个查询
$m=Carbon::parse($request->date);
Gk::where('user_id',$request->user_id)->whereRaw(DB::raw("YEAR(created_at)=$m->year"))->whereRaw(DB::raw("MONTH(created_at)=$m->month"))
->orderBy('created_at','desc')
->get();
第二个查询返回任何月份的所有行。我在foreach循环中执行这个查询,用于第一个查询返回的所有月份。
我正在尝试将这两个查询合并为一个查询,以便可以按月份和年份获取一组结果,以及该月份的所有详细信息。
任何帮助、建议或想法都会非常有帮助。
[注意:对于第二个查询中的日期,此日期是第一个查询的结果。]
谢谢您。
最佳答案
我阅读您的问题的方式如下:第二个查询在循环中执行,结果来自第一个查询。对吗在我的回答中,我解释了一种只执行一次而不是在循环中执行第二个查询的方法。您仍然需要执行第一个查询一次。
因此,我认为您最好使用Php收集方法:
$results = Gk::where('user_id',$request->user_id)
->orderBy('created_at','desc')
->get()
->groupBy(function (Gk $item) {
return $item->created_at->format('Y-m');
});
groupBy
方法必须返回要对其元素进行分组的属性。对于这个例子,我认为使用yyyy-mm
格式会很好。参考:https://laravel.com/docs/5.5/collections#method-groupby
编辑:也许您还可以去掉orderBy方法调用,因为您在以后按分组:
$results = Gk::where('user_id',$request->user_id)
->get()
->groupBy(function (Gk $item) {
return $item->created_at->format('Y-m');
});
编辑2:若要合并两个查询的信息,可以执行以下操作:
$results = Gk::where('user_id',$request->user_id)
->get()
->groupBy(function (Gk $item) {
return $item->created_at->format('Y-m');
})->map(function(Collection $rows) {
return [
'sum(ton)' => $rows->sum('ton'),
'total' => $rows->count(),
'sum(w)' => $rows->sum('w'),
'rows' => $rows
];
);
请注意,我在第一个查询中省略了一些选定列,因为它们在给定的分组依据中不唯一。但是可以在map函数中添加任何逻辑。因为我们在
map()
之后使用groupBy
,所以每次调用map()
都会收到一个月的项目集合。您可以使用这个神奇的集合来计算您需要的所有值,并将查询数减少到一个。