使用连接和不同的 Laravel 求和查询
Posted
技术标签:
【中文标题】使用连接和不同的 Laravel 求和查询【英文标题】:Laravel sum query using join and distinct 【发布时间】:2020-01-05 16:33:14 【问题描述】:我有 2 个表要使用 join
查询,即 loans
和 amortizations
表。
Loans
表有很多摊销,所以loans.id
是对amortizations
表中amortizations.loan_id
的引用。
Loan id:3
在amortizations table
中存在两次,每个都有一个value=10,800
。Loan id:5
在amortizations table
中也存在两次,每个都有一个value=11,100
,Loan id:11
也是如此在amortizations table
中存在两次,每个都有一个value=5400
。
当你把它加起来时,total
就是54,600
。但我希望 id 是不同的,这样这些值就不会添加两次。所以总数将等于27,300
。即使在 Laravel 中使用 distinct()
,我下面的现有查询也会返回 54,600
值而不是 27,300
。我将如何实现这一目标?
Controller query
$oneToThirtyDue = Amortization::distinct('amortizations.loan_id')
->join('loans', 'loans.id', '=', 'amortizations.loan_id')
->select('loans.loan_type',\DB::raw('SUM(loans.loan_balance) as total_val'))
->where('amortizations.payment_status',0)
->where('amortizations.schedule', '<', date('Y-m-d'))
->where('amortizations.past_due', '<=', 30)
->groupBy('loans.loan_type')
->orderBy('loans.loan_type')
->get();
请帮忙。非常感谢。
【问题讨论】:
你能把你的加入切换到这个并告诉我们结果是什么吗?Amortization::distinct('amortizations.loan_id') ->join('loans', 'amortizations.loan_id', '=', 'loans.id')
结果是一样的先生
尝试将所有列用于不同的功能。 Amortization::distinct('amortizations.load_id','value', 'column3'....)
都不行 :(
我能想到的最后一件事是使用 DB::Raw() 函数来选择不同的 Amortization.loadId。您可以在以下链接中详细了解它:link。使用 DB::raw() 应该让你使用原始 sql 语句。
【参考方案1】:
$idsDue = Amortization::distinct()
->select('loan_id')
->where('payment_status',0)
->where('schedule', '<', date('Y-m-d'))
->where('past_due', '<=', 30)
->get();
$oneToThirtyDue = Loan::select('loan_type',\DB::raw('SUM(loan_balance) as total_val'))
->whereIn('id',$idsDue)
->groupBy('loan_type')
->orderBy('loan_type')
->get();
【讨论】:
恭喜,你明天应该把它标记为正确。【参考方案2】:我相信这个问题是在不同发生之前将为组中的所有行计算最大值。同时 distinct 将在整个行上运行,在最大值之后所以我没有帮助。
因此,我相信子查询可以解决您的大部分问题。方法是在加入之前减少Amortization
中的重复项。这将使连接成为 1 对 1,而不是当您有重复时有时是 2-1。为方便起见,反转连接并使用 group by 来避免重复并获得 max 的额外列,因为它们不在 group by 中。在某些测试表上进行本地测试的类似查询,因此应该可以实现。
$subQuery = Amortization::select(
'loan_id',
DB::raw('max(amortizations.id) as id'),
DB::raw('max(amortizations.payment_status) as payment_status'),
DB::raw('max(amortizations.schedule) as schedule'),
DB::raw('max(amortizations.past_due) as past_due')
)->groupBy('loan_id');
Loan::join(DB::raw("($subQuery->toSql()) as amortizations"), 'amortizations.loan_id', '=', 'loans.id')
->select('loans.loan_type',\DB::raw('SUM(loans.loan_balance) as total_val'))
->where('amortizations.payment_status',0)
->where('amortizations.schedule', '<', date('Y-m-d'))
->where('amortizations.past_due', '<=', 30)
->orderBy('loans.loan_type');
这必须通过DB::raw
来完成,但我目前看不到更好的方法,select 语句之外的子查询是Laravel
中的灰色区域。
【讨论】:
以上是关于使用连接和不同的 Laravel 求和查询的主要内容,如果未能解决你的问题,请参考以下文章