【问题标题】:Laravel Group and Sum hasMany RelationshipLaravel Group 和 Sum hasMany 关系
【发布时间】:2020-05-25 01:12:43
【问题描述】:

我有一个 users 表,其中有一列 country 和用户 belongsToMany 类别。用户还 hasManyPayments 表建立关系。

我正在尝试:

  1. 按国家/地区对用户进行分组,显示每个国家/地区最受欢迎的类别(已解决)
  2. payments 表中每个分组国家/地区的amount 列相加

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

以下是表结构:

用户

id | name  | country

1  | UserA | Canada
2  | UserB | USA
3  | UserC | Canada

类别

id | Name
1  | Housing
2  | Cooking

category_user

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(金额)作为 total_payments。任何帮助将不胜感激。

谢谢。

【问题讨论】:

  • @Ersoy 您的输入将不胜感激????????
  • sums 会与类别相关吗?是sum of canada 还是sum of canada for housing
  • 只为国家。例如:sum of canada
  • 还有一个问题,totaltotal number of payments 还是 total number of users in the top category ?由于用户可以在相同/不同类别中进行多次付款,因此不清楚在这种情况下总付款是多少?
  • 好的,我需要查看 1.) 每个国家/地区,2.) 该国家/地区的用户总数,3.) 该国家/地区最受欢迎的类别和 4.)国家。

标签: php mysql laravel


【解决方案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"
  }
]

【讨论】:

  • 非常感谢 Ersoy!非常感谢您的帮助。
猜你喜欢
  • 2021-12-14
  • 2021-03-22
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 2020-03-25
  • 2021-09-24
  • 2016-03-17
  • 1970-01-01
相关资源
最近更新 更多