Select 在 Laravel 中使用 whereHas 时来自子查询的 SUM

Select SUM from subquery while using whereHas in Laravel

我有 2 个表,customerscustomer_invoices,我想让所有客户在他们的发票上有条件,并且 select 特定列(customers.id, customers.last_name, 以及每个客户的发票总和 total_price), 我有这个查询:

$result = Customer::whereHas('customerInvoices', function(Builder $q) {
            $q->where('customer_invoices.status', 1);
        })->select([
            'customers.id',
            'customers.last_name',
            \DB::raw('SUM(customer_invoices.total_price) as sum')
        ])->get();

customerInvoices 是关系:

public function customerInvoices() {

    return $this->hasMany(CustomerInvoice::class);
}

我想使用子查询而不是连接,所以这里我不能select这个\DB::raw('SUM(customer_invoices.total_price) as sum'),否则我当然会得到这个错误:

"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'customer_invoices.total_price' in 'field list' (SQL: select `customers`.`id`, `customers`.`last_name`, SUM(customer_invoices.total_price) as sum from `customers` where exists (select * from `customer_invoices` where `customers`.`id` = `customer_invoices`.`customer_id` and `customer_invoices`.`status` = 1))"

如何在不使用联接的情况下实现此目的?

您可以使用 withCount() 从相关模型中获取总和,如

$result = Customer::select([
            'customers.id',
            'customers.last_name'
        ])->withCount([
            'customerInvoices as invoice_sum' => function($query) {
                $query->select(DB::raw('SUM(total_price)'));
            }
        ])->whereHas('customerInvoices', function(Builder $q) {
            $q->where('customer_invoices.status', 1);
        })->get();

另一种求和的方法,您可以在客户模型中定义一个 hasOne() 关系,例如

public function invoice_sum()
{
    return $this->hasOne(CustomerInvoice::class)
        ->select('customer_id',
            DB::raw('sum(total_price)')
        )->groupBy('customer_id');
}

并在查询生成器中

$result = Customer::select([
            'customers.id',
            'customers.last_name',
        ])->with('invoice_sum')
          ->whereHas('customerInvoices', function(Builder $q) {
            $q->where('customer_invoices.status', 1);
        })->get();      

根据Eloquent : withCount() overrides the $columns on get() issue 首先放置select() mehtod 然后使用with() 函数