[英]How to substract two sums of columns from two different joins in laravel?
I have an articles
table and I want to join two different tables where I track income and outcome articles.我有一个
articles
表,我想加入两个不同的表来跟踪收入和结果文章。 I want to substract sum of quantities from one table with sum of quantities from another table.我想用另一个表中的数量总和减去一个表中的数量总和。 This is what I try but I always get null in quantity.
这是我尝试的,但我的数量总是为零。
return DB::table('articles')
->leftJoin('article_incoming_document', function ($join) use ($warehouse, $warehouseType) {
$join->on('articles.id', '=', 'article_incoming_document.article_id')
->where('article_incoming_document.warehouse', '=', $warehouse)
->where('article_incoming_document.warehouse_type', '=', $warehouseType);
})
->leftJoin('article_outgoing_document', function ($join) use ($warehouse, $warehouseType) {
$join->on('articles.id', '=', 'article_outgoing_document.article_id')
->where('article_outgoing_document.warehouse', '=', $warehouse)
->where('article_outgoing_document.warehouse_type', '=', $warehouseType);
})
->select([
'articles.id',
'articles.name',
DB::raw('(SUM(article_incoming_document.quantity) - SUM(article_outgoing_document.quantity)) as quantity'),
])
->where('quantity', '>', 0)
->groupBy('articles.id');
Using multiple joins in query will result in multiple rows for example if one article has 2 rows from incoming table 2 or more related rows from outgoing table which will produce incorrect sum value.在查询中使用多个连接将导致多行,例如,如果一篇文章有来自传入表 2 的 2 行或来自传出表的更多相关行,这将产生不正确的总和值。 To handle such type of issue you can use sub clauses for your related tables (incoming and outgoing) and calculate sum for each article in their respective sub cause.
要处理此类问题,您可以对相关表(传入和传出)使用子子句,并在其各自的子原因中计算每篇文章的总和。 After that join these sub clauses with your article table and subtract their quantity.
之后,将这些子条款与您的文章表结合并减去它们的数量。
In plain SQL it would look like在普通的 SQL 中,它看起来像
select a.id,
a.name,
coalesce(i.quantity,0) - coalesce(o.quantity,0) as quantity
from articles as a
left join (
select article_id,sum(quantity) as quantity
from article_incoming_document
where warehous = :warehouse
and warehouse_type: warehouse_type
group by article_id
) i on a.id = i.article_id
left join (
select article_id,sum(quantity) as quantity
from article_outgoing_document
where warehous = :warehouse
and warehouse_type: warehouse_type
group by article_id
) o on a.id = o.article_id
having quantity > 0 // or where (i.quantity - o.quantity) > 0
In newer versions of laravel you can use leftJoinSub在较新版本的 Laravel 中,您可以使用leftJoinSub
$articleIncoming = DB::table('article_incoming_document')
->select('article_id', DB::raw('sum(quantity) as quantity'))
->where('warehouse', $warehouse)
->where('warehouse_type', '=', $warehouseType)
->groupBy('article_id');
$articleOutgoing = DB::table('article_outgoing_document')
->select('article_id', DB::raw('sum(quantity) as quantity'))
->where('warehouse', $warehouse)
->where('warehouse_type', '=', $warehouseType)
->groupBy('article_id');
$articles = DB::table('articles as a')
->leftJoinSub($articleIncoming, 'i', function ($join) {
$join->on('a.id', '=', 'i.article_id');
})
->leftJoinSub($articleOutgoing, 'o', function ($join) {
$join->on('a.id', '=', 'o.article_id');
})
//->where('i/o.quantity', '>', 0) ?? specify quantity of incoming or outgoing, in case of both then add another where clause
->select([
'a.id',
'a.name',
DB::raw('coalesce(i.quantity,0) - coalesce(o.quantity,0) as quantity')
])
//->having('quantity', '>', 0) ?? if you want to perform filter on subtraction of incoming and outgoing quantity then use having clause
->get();
Additionally I have used coalesce over result of sum(quantity)
to ignore nulls like另外,我在
sum(quantity)
结果上使用了合并来忽略空值,例如
coalesce(i.quantity,0) - coalesce(o.quantity,0) as quantity
DB::raw('coalesce(i.quantity,0) - coalesce(o.quantity,0) as quantity')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.