Laravel Group 和 Sum hasMany 的关系

我有一个users包含列country和用户belongsToMany Categories 的表。用户还hasManyPayments表有关系。

我在尝试着:

  1. 按国家/地区对用户进行分组,显示每个国家/地区最受欢迎的类别(这已经解决)

  2. 对每个分组国家/地区的表amount中的列求和payments

每次我尝试加入payments表格时,它都会返回多个结果,这使得总和完全错误。我相信我没有使用正确的查询。

以下是表结构:

用户

id | name  | country


1  | UserA | Canada

2  | UserB | USA

3  | UserC | Canada

类别


id | Name

1  | Housing

2  | Cooking

类别_用户


id  | category_id | user_id

1   | 1           | 1

2   | 2           | 2

3   | 1           | 3

付款


id | amount | user_id

1  | 500    | 1

2  | 200    | 2

3  | 150    | 1

4  | 100    | 3

第一个问题已使用以下代码解决:


return User::leftJoin('category_user as cu', 'users.id', '=', 'cu.user_id')

        ->join('categories as c', 'cu.category_id', '=', 'c.id')

        ->groupBy(['country', 'c.name'])

        ->get([

            'users.country',

            'c.name',

            DB::raw('count(*) as total')

        ])

        ->groupBy('country')

        ->values()

        ->map(function (Collection $elt) {

            return $elt->sortByDesc('total')->first();

        });

结果是这样的:


[

  {

    "country": "Canada",

    "name": "Housing",

    "total": 2

  },

  {

    "country": "USA",

    "name": "Cooking",

    "total": 1

  }

]

我想从付款中获得 SUM(amount) 作为 total_payments。任何帮助,将不胜感激。


谢谢。


慕虎7371278
浏览 120回答 1
1回答

繁星淼淼

我找不到减少查询数量的方法,但在我的本地测试中进行了后续工作。public function foobar(){    $popular = User::leftJoin('category_user as cu', 'users.id', '=', 'cu.user_id')        ->join('categories as c', 'cu.category_id', '=', 'c.id')        ->groupBy(['country', 'c.name'])        ->get([            'users.country',            'c.name',            DB::raw('count(*) as total')        ])        ->groupBy('country')        ->values()        ->map(function (Collection $elt) {            return $elt->sortByDesc('total')->first();        }); // this one is same (to get popular category)    // this one for payments and number of users from that country    return User::leftJoin('payments as p', 'users.id', '=', 'p.user_id')        ->groupBy('country')        ->get(['country', DB::raw('sum(p.amount) as total'), DB::raw('count(distinct(users.id)) as userCount')])        ->map(function ($col) use ($popular) { // merging two collections into one            $col->name = $popular->where('country', $col->country)->first()->name;            return $col;        });}它打印出这样的东西;[  {    "country": "Canada",    "total": "1150",    "userCount": 2,    "name": "Housing"  },  {    "country": "Italy",    "total": "100",    "userCount": 1,    "name": "Kitchen"  },  {    "country": "USA",    "total": "200",    "userCount": 1,    "name": "Cooking"  }]
打开App,查看更多内容
随时随地看视频慕课网APP