Laravel中如何按差异条件统计工具的危险/安全状态数量?
统计关联表中工具的安全/危险数量
数据库结构
-- tools表 id (主键)、name -- details表 id (主键)、balance_shoot、tool_id (关联tools.id)
需求说明
需要统计与details表关联的工具中,满足以下条件的数量:
- 危险数量(danger_count):关联的details表中
balance_shoot ≤ 0的工具数 - 安全数量(save_count):关联的details表中
balance_shoot > 0的工具数
期望返回结果格式:["danger_count"=>0, "save_count"=>5]
现有代码片段
public function index(Request $request){ $trans_date = date('Y-m-d'); $tools = Tool::select('id') ->whereHas('details', function ($query) use ($trans_date) { // 这里应该是你原本要加的日期条件? }); }
完整解决方案
我来帮你把代码补全,直接通过数据库聚合查询就能高效得到结果,不用先查数据再遍历统计:
public function index(Request $request){ $trans_date = date('Y-m-d'); $result = Tool::select( DB::raw('SUM(CASE WHEN details.balance_shoot <= 0 THEN 1 ELSE 0 END) as danger_count'), DB::raw('SUM(CASE WHEN details.balance_shoot > 0 THEN 1 ELSE 0 END) as save_count') ) ->join('details', 'tools.id', '=', 'details.tool_id') // 如果需要按日期过滤details数据,取消下面这行注释即可 // ->whereDate('details.created_at', $trans_date) ->first(); // 转换为你想要的数组格式,同时处理null值为0 return [ 'danger_count' => (int)$result->danger_count ?: 0, 'save_count' => (int)$result->save_count ?: 0 ]; }
额外优化场景
如果一个工具对应多条details记录,你希望每个工具只被统计一次(比如只要有一条满足危险条件就算危险工具),可以用下面的写法:
$result = Tool::select( DB::raw('SUM(CASE WHEN EXISTS (SELECT 1 FROM details WHERE details.tool_id = tools.id AND details.balance_shoot <= 0) THEN 1 ELSE 0 END) as danger_count'), DB::raw('SUM(CASE WHEN EXISTS (SELECT 1 FROM details WHERE details.tool_id = tools.id AND details.balance_shoot > 0) THEN 1 ELSE 0 END) as save_count') ) ->whereHas('details') // 只统计有关联details的工具 ->first();
这样就能避免同一工具被重复统计的问题啦~
内容的提问来源于stack exchange,提问作者punk73
相关产品推荐
相关产品推荐

