为了账号安全,请及时绑定邮箱和手机立即绑定

Laravel Group 和 Sum hasMany 的关系

Laravel Group 和 Sum hasMany 的关系

PHP
慕虎7371278 2023-04-15 17:07:04
我有一个users包含列country和用户belongsToMany Categories 的表。用户还hasMany与Payments表有关系。我在尝试着:按国家/地区对用户进行分组,显示每个国家/地区最受欢迎的类别(这已经解决)对每个分组国家/地区的表amount中的列求和payments每次我尝试加入payments表格时,它都会返回多个结果,这使得总和完全错误。我相信我没有使用正确的查询。以下是表结构:用户id | name  | country1  | UserA | Canada2  | UserB | USA3  | UserC | Canada类别id | Name1  | Housing2  | Cooking类别_用户id  | category_id | user_id1   | 1           | 12   | 2           | 23   | 1           | 3付款id | amount | user_id1  | 500    | 12  | 200    | 23  | 150    | 14  | 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。任何帮助,将不胜感激。谢谢。
查看完整描述

1 回答

?
繁星淼淼

TA贡献1775条经验 获得超11个赞

我找不到减少查询数量的方法,但在我的本地测试中进行了后续工作。


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"

  }

]


查看完整回答
反对 回复 2023-04-15
  • 1 回答
  • 0 关注
  • 133 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信