Laravel Eloquent GroupBy 多对一关系
Posted
技术标签:
【中文标题】Laravel Eloquent GroupBy 多对一关系【英文标题】:Laravel Eloquent GroupBy Many To One Relationship 【发布时间】:2021-04-21 05:45:00 【问题描述】:我有下表结构:
用户表
id | name | balance |
---|---|---|
1 | user 1 | 4 |
2 | user 2 | 2 |
3 | user 3 | 2 |
special_user 表
id | user_id | status |
---|---|---|
1 | 1 | 1 |
2 | 2 | 1 |
订单表
id | user_id | provider | amount | date |
---|---|---|---|---|
1 | 1 | Provider 1 | 10 | 16-01-2021 |
2 | 2 | Provider 2 | 20 | 16-01-2021 |
3 | 3 | Provider 1 | 10 | 16-01-2021 |
4 | 3 | Provider 1 | 50 | 16-01-2021 |
5 | 1 | Provider 3 | 15 | 16-01-2021 |
6 | 2 | Provider 1 | 20 | 16-01-2021 |
我想要在刀片中的输出 html 表是(对于 16-01-2021)
Provider | Users(amount) | Special User (amount) | Total Amount |
---|---|---|---|
Provider 1 | 1 ($60) | 2 ($30) | $90 |
Provider 2 | 0 ($0) | 1 ($20) | $20 |
Provider 3 | 0 ($0) | 1 ($15) | $15 |
Users 是他们的 ID 不在 special_user 表中的用户计数。
特殊用户是他们的 user_id 在 special_user 表中的特殊用户计数
(金额)是各类用户的订单金额之和
总金额是用户金额和特殊用户金额的总和。
以下是我尝试过的代码:
$top_providers = Orders::
whereNotNull('provider)
->whereBetween('created_at', [$start_1, $end_1])
->groupBy('provider')
->selectRaw('*, count(*) as total_trans, count(transactions.user_id) as
all_users_count')
->get();
上面的代码确实根据提供者对订单进行分组,但我无法对用户类型进行分组。
请帮忙。
谢谢
【问题讨论】:
我已经格式化了表格,请帮忙!!! 我无法获得的是用户和特殊用户列 【参考方案1】:要获得所需的结果集,您可以执行 2 个查询,一个将获取特殊用户的 id,第二个将使用这些 id 在用户之间进行分叉
在普通 SQL 中,查询看起来像
select
provider,
sum(case when user_id not in(1,2) then 1 else 0 end) user_count,
sum(case when user_id not in(1,2) then amount else 0 end) user_amount,
sum(case when user_id in(1,2) then 1 else 0 end) special_user_count,
sum(case when user_id in(1,2) then amount else 0 end) special_user_amount,
sum(amount) total
from orders
group by provider
DEMO
在 laravel 中,您可以使用带有原始方法的查询构建器
$specialUserIds = SpecialUsers::where('status' , 1)->pluck('user_id')->toArray();
$orders = DB::table('orders')
->select('provider',
DB::raw('sum(case when user_id not in('.$specialUserIds.') then 1 else 0 end) user_count'),
DB::raw('sum(case when user_id not in('.$specialUserIds.') then amount else 0 end) user_amount'),
DB::raw('sum(case when user_id in('.$specialUserIds.') then 1 else 0 end) special_user_count'),
DB::raw('sum(case when user_id in('.$specialUserIds.') then amount else 0 end) special_user_amount'),
DB::raw('sum(amount) total')
)
->whereNotNull('provider')
->whereBetween('created_at', [$start_1, $end_1])
->groupBy('provider')
->get();
或者你可以通过selectRaw使用参数绑定
另外,如果用户的特殊用户表中只有一行,我建议将该状态属性移动到主用户表中,而不是创建两个具有一对一关系的表
【讨论】:
以上是关于Laravel Eloquent GroupBy 多对一关系的主要内容,如果未能解决你的问题,请参考以下文章
GroupBy() 覆盖我的选择语句 Eloquent Laravel
Laravel Eloquent GroupBy 多对一关系
Laravel 6,MYSQL - 如何使用 Laravel Querybuilder 或 Model Eloquent 将子查询与 GroupBY 左连接?
Laravel Eloquent groupBy() 并且还返回每个组的计数