我有一个
orders
表,需要根据具体条件组合多个计数。
目前我有 3 个疑问:
$orderCount = Order::count();
$newOrderCount = Order::where('status', '=', 'new')->count();
$completedOrderCount = Order::where('status', '=', 'completed')->count();
如何将其合并为 1 个查询?
不是雄辩,而是我想到的第一个解决方案
DB::table('orders')
->select(DB::raw('count(*) as order_count'))
->addSelect(DB::raw('sum(case when status = "new" then 1 else 0 end) as new_orders_count'))
->addSelect(DB::raw('sum(case when status = "completed" then 1 else 0 end) as completed_orders_count'))
->get();
或者用集合来做:
$orders = Order::all();
$orderCount = $orders->count();
$newOrderCount = $orders->where('status', '=', 'new')->count();
$completedOrderCount = $orders->where('status', '=', 'completed')->count();
这是一个冗长的解决方案,但也能达到目的。
$orders = Order::all(['id'])->toArray();
$orderCount = 0;
$newOrderCount = 0;
$completedOrderCount = 0;
array_map(function ($o) use (&$orderCount, &$newOrderCount, &$completedOrderCount) {
$orderCount++;
if($o['status'] === 'new')
$newOrderCount++;
if($o['status'] === 'completed')
$completedOrderCount++;
}, $orders);
当您希望按条件进行计数时,在
SUM()
方法调用中使用 selectRaw()
—— 这提供了简洁的语法,因为不需要显式编写 CASE
或 IF
表达式。
代码:(PHPize演示)
var_export(
$db::table('orders')
->selectRaw("COUNT(1) count")
->selectRaw("SUM(status = 'new') new")
->selectRaw("SUM(status = 'complete') complete")
->first()
);
为了使用一些有趣的收集方法,您可以在
countBy
列上调用 status
来创建唯一状态及其计数对(不会包含零计数),然后附加总计数。 (PHPize 演示)
var_export(
$db::table('orders')
->get()
->countBy('status')
->pipe(
fn($coll) => $coll->put('count', $coll->sum())
)
->toArray()
);