You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:18:39