使用Eloquent获取按月分组的摘要

时间:2018-01-05 07:55:41

标签: php mysql laravel laravel-5 eloquent

我有一个名为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循环中为第一个查询中返回的所有月份执行此查询。

我正在尝试将这两个查询合并为一个,以便我可以按月和年获得一组结果以及该月的所有详细信息。

任何帮助,建议或想法都会非常有帮助。

[注意:对于第二个查询中的日期,此日期是created_at来自第一个查询的结果。]

谢谢。

1 个答案:

答案 0 :(得分:1)

我阅读您的问题的方式如下:第二个查询在循环中执行,其结果来自第一个查询。是对的吗?在我的回答中,我已经解释了一种只执行第二次查询而不是循环的方法。你仍然需要执行一次第一次查询。

所以,我认为你最好使用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()之后使用groupBy,因此map()的每次调用都会收到一个月的项目集合。您可以使用这个神奇的集合魔法来计算您需要的所有值,并将查询数量减少到只有一个。