在 Laravel 中使用 whereHas 时从子查询中选择 SUM
我有 2 个表,customers
和 customer_invoices
,我想获取所有客户的发票条件,并选择特定列(customers.id、customer.last_name,以及每个客户发票的 total_price
总和),我有这个查询:
I have 2 tables, customers
and customer_invoices
, and I want to get all the customers with a condition on their invoices, and select specific columns (customers.id, customers.last_name, and the sum of the total_price
of the invoices for each customer), I have this query :
$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);
}
我想使用子查询而不是连接,所以这里我不能选择这个 DB::raw('SUM(customer_invoices.total_price) as sum')
,否则我会得到这个当然是错误的:
I want to use subqueries instead of joins, so here I can't select this DB::raw('SUM(customer_invoices.total_price) as sum')
, or else I get this error of course :
"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))"
如何在不使用连接的情况下实现这一点?
How can I achieve this without using joins ?
推荐答案
你可以使用 withCount()
从相关模型中获取总和为
You can use withCount()
to get sum from related model as
$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();
另一种获取总和的方法,您可以在 Customer 模型中定义 hasOne()
关系,例如
Another approach to get sum, you can define a hasOne()
relation in your Customer model like
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() 会覆盖 get() 上的 $columns先发出 select()
方法,然后使用 with()
函数
As per Eloquent : withCount() overrides the $columns on get() issue first put select()
mehtod and then use with()
function
相关文章