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

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

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

Loan id:3amortizations table 中存在两次,每个都有一个value=10,800
Loan 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 语句。

标签: sql laravel join eloquent


【解决方案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 中的灰色区域。

【讨论】:

    猜你喜欢
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    相关资源
    最近更新 更多