将不同的 select 求和查询与来自相同 table 的不同位置相结合(Laravel 方式)
Combining different select sum queries with different where from same table (Laravel way)
我有稍微不同的 select 查询来从相同的 table 读取数据。
select user_id
, SUM(credit_movement) as testing_fees
from transactions
where `type` in ('Testing', 'Testing Data')
and `user_id` in (118,124,352 ...)
group by `user_id`
select user_id, SUM(credit_movement) as production_fees
from `transactions`
where `type` in ('Production', 'Production Data') and `user_id` in (152,521,1341, ...)
group by `user_id`
type
和 user_id
正在改变。
在 Laravel 中,我最终对每种类型使用了 1 个查询,但有 10 种类型,这意味着 10 个数据库连接 - 这并不好。
$values['testing_fees'] = \DB::table("transactions")
->select(\DB::raw("user_id, SUM(credit_movement) as testing_fees"))
->whereIn('type', ["Testing", "Testing Data"])
->whereIn('user_id', $userIdsToBeUsed)
->whereDate('created_at', '>=', $fromDate->toDateString())
->whereDate('created_at', '<=', $toDate->toDateString())
->groupBy('user_id')
->get();
$values['production_fees'] = \DB::table("transactions")
->select(\DB::raw("user_id, SUM(credit_movement) as production_fees"))
->whereIn('type', ["Production", "Production Data"])
->whereIn('user_id', $userIdsToBeUsed)
->whereDate('created_at', '>=', $fromDate->toDateString()) // this is common
->whereDate('created_at', '<=', $toDate->toDateString()) // this is common
->groupBy('user_id') // this is common
->get();
有什么好方法可以将这些查询组合成一个查询,以便我建立 1 个数据库连接来获取所有数据?
(我正在寻找 Laravel 查询生成器实现此目的的方法)
您可以使用 UNION 关键字:https://www.w3schools.com/sql/sql_ref_union.asp
所以组合查询将是这样的:
select user_id
, SUM(credit_movement) as testing_fees
from transactions
where `type` in ('Testing', 'Testing Data')
and `user_id` in (118,124,352 ...)
group by `user_id`
UNION
select user_id, SUM(credit_movement) as production_fees
from `transactions`
where `type` in ('Production', 'Production Data') and `user_id` in (152,521,1341, ...)
group by `user_id`
如果需要允许重复,请使用 UNION ALL
而不是 UNION
如果您想避免混淆哪个是哪个,您可以使用第三个键来告诉您正在处理的数据类型。查看 Laravel docs
,您的代码应如下所示:
<?php
$values['testing_fees'] = \DB::table("transactions")
->select(\DB::raw("user_id, SUM(credit_movement) as testing_fees,'testing as type'"))
->whereIn('type', ["Testing", "Testing Data"])
->whereIn('user_id', $userIdsToBeUsed)
->whereDate('created_at', '>=', $fromDate->toDateString())
->whereDate('created_at', '<=', $toDate->toDateString())
->groupBy('user_id');
$values['production_fees'] = \DB::table("transactions")
->select(\DB::raw("user_id, SUM(credit_movement) as production_fees,'production' as type"))
->whereIn('type', ["Production", "Production Data"])
->whereIn('user_id', $userIdsToBeUsed)
->whereDate('created_at', '>=', $fromDate->toDateString()) // this is common
->whereDate('created_at', '<=', $toDate->toDateString()) // this is common
->groupBy('user_id'); // this is common
// and so on for $values
$query = array_shift($values);
foreach($values as $key => $sub_query){
$query->union($sub_query);
}
$data = $query->get();
dd($data);
注意: ->get()
仅在我们 union
编辑了所有子查询后才适用。
我有稍微不同的 select 查询来从相同的 table 读取数据。
select user_id
, SUM(credit_movement) as testing_fees
from transactions
where `type` in ('Testing', 'Testing Data')
and `user_id` in (118,124,352 ...)
group by `user_id`
select user_id, SUM(credit_movement) as production_fees
from `transactions`
where `type` in ('Production', 'Production Data') and `user_id` in (152,521,1341, ...)
group by `user_id`
type
和 user_id
正在改变。
在 Laravel 中,我最终对每种类型使用了 1 个查询,但有 10 种类型,这意味着 10 个数据库连接 - 这并不好。
$values['testing_fees'] = \DB::table("transactions")
->select(\DB::raw("user_id, SUM(credit_movement) as testing_fees"))
->whereIn('type', ["Testing", "Testing Data"])
->whereIn('user_id', $userIdsToBeUsed)
->whereDate('created_at', '>=', $fromDate->toDateString())
->whereDate('created_at', '<=', $toDate->toDateString())
->groupBy('user_id')
->get();
$values['production_fees'] = \DB::table("transactions")
->select(\DB::raw("user_id, SUM(credit_movement) as production_fees"))
->whereIn('type', ["Production", "Production Data"])
->whereIn('user_id', $userIdsToBeUsed)
->whereDate('created_at', '>=', $fromDate->toDateString()) // this is common
->whereDate('created_at', '<=', $toDate->toDateString()) // this is common
->groupBy('user_id') // this is common
->get();
有什么好方法可以将这些查询组合成一个查询,以便我建立 1 个数据库连接来获取所有数据?
(我正在寻找 Laravel 查询生成器实现此目的的方法)
您可以使用 UNION 关键字:https://www.w3schools.com/sql/sql_ref_union.asp
所以组合查询将是这样的:
select user_id
, SUM(credit_movement) as testing_fees
from transactions
where `type` in ('Testing', 'Testing Data')
and `user_id` in (118,124,352 ...)
group by `user_id`
UNION
select user_id, SUM(credit_movement) as production_fees
from `transactions`
where `type` in ('Production', 'Production Data') and `user_id` in (152,521,1341, ...)
group by `user_id`
如果需要允许重复,请使用 UNION ALL
而不是 UNION
如果您想避免混淆哪个是哪个,您可以使用第三个键来告诉您正在处理的数据类型。查看 Laravel docs
,您的代码应如下所示:
<?php
$values['testing_fees'] = \DB::table("transactions")
->select(\DB::raw("user_id, SUM(credit_movement) as testing_fees,'testing as type'"))
->whereIn('type', ["Testing", "Testing Data"])
->whereIn('user_id', $userIdsToBeUsed)
->whereDate('created_at', '>=', $fromDate->toDateString())
->whereDate('created_at', '<=', $toDate->toDateString())
->groupBy('user_id');
$values['production_fees'] = \DB::table("transactions")
->select(\DB::raw("user_id, SUM(credit_movement) as production_fees,'production' as type"))
->whereIn('type', ["Production", "Production Data"])
->whereIn('user_id', $userIdsToBeUsed)
->whereDate('created_at', '>=', $fromDate->toDateString()) // this is common
->whereDate('created_at', '<=', $toDate->toDateString()) // this is common
->groupBy('user_id'); // this is common
// and so on for $values
$query = array_shift($values);
foreach($values as $key => $sub_query){
$query->union($sub_query);
}
$data = $query->get();
dd($data);
注意: ->get()
仅在我们 union
编辑了所有子查询后才适用。