使用连接和不同的 Laravel 求和查询

Posted

技术标签:

【中文标题】使用连接和不同的 Laravel 求和查询【英文标题】:Laravel sum query using join and distinct 【发布时间】:2020-01-05 16:33:14 【问题描述】:

我有 2 个表要使用 join 查询,即 loansamortizations 表。

Loans 表有很多摊销,所以loans.id 是对amortizations 表中amortizations.loan_id 的引用。

Loan id:3amortizations table 中存在两次,每个都有一个value=10,800Loan id:5amortizations table 中也存在两次,每个都有一个value=11,100Loan 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') -&gt;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 求和查询的主要内容,如果未能解决你的问题,请参考以下文章

在 laravel 数据库查询中求和

如何使用 Laravel Eloquent 在不同服务器上的多个数据库之间执行连接查询?

Laravel 查询生成器对多列求和

如何在laravel中的子查询中求和

在 Laravel Eloquent 中求和并返回页面

Laravel 5 - 文件上传