You need to enable JavaScript to run this app. Laravel Eloquent 如何查询符合条件的魅力与说服力评估总经验值最高用户
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent 如何查询符合条件的魅力与说服力评估总经验值最高用户

实现方案

核心逻辑

不需要预加载全部evaluations关联数据,直接在数据库层完成总分计算,相比将关联数据拉取到PHP内存遍历求和,查询效率更高,也能直接按总分排序定位目标用户。
对应计算规则拆解:

  • 单独统计每个用户所有charisma = true的evaluations记录的exp求和值
  • 单独统计每个用户所有persuasion = true的evaluations记录的exp求和值
  • 两个求和值相加为用户总评估分,空值统一处理为0
  • 沿用原有筛选条件:匹配指定commision_id、关联角色level=2,按总评估分倒序取第一条即为目标用户

可直接复用的实现代码

原生selectRaw写法

$topUser = User::query()
    // 原有基础筛选条件
    ->where('commision_id', $data['commision'])
    ->whereHas('role', function ($query) {
        $query->where('level', 2);
    })
    // 关联计算总分,兼容空值异常
    ->selectRaw(
        'users.*, COALESCE(
            (
                SELECT COALESCE(SUM(exp), 0)
                FROM evaluations
                WHERE evaluations.user_id = users.id
                AND charisma = true
                AND exp IS NOT NULL
            )
            +
            (
                SELECT COALESCE(SUM(exp), 0)
                FROM evaluations
                WHERE evaluations.user_id = users.id
                AND persuasion = true
                AND exp IS NOT NULL
            ),
            0
        ) AS total_eval_score'
    )
    // 按总分倒序取最高
    ->orderByDesc('total_eval_score')
    ->first();

Laravel内置关联聚合写法

如果习惯使用框架封装的withSum关联聚合语法,可使用等效写法,代码可读性更强:

$topUser = User::query()
    ->where('commision_id', $data['commision'])
    ->whereHas('role', function ($query) {
        $query->where('level', 2);
    })
    // 分别计算两个维度的exp总和,自动生成关联聚合字段
    ->withSum([
        'evaluations as charisma_exp_sum' => function ($query) {
            $query->where('charisma', true)->selectRaw('COALESCE(SUM(exp), 0)');
        },
        'evaluations as persuasion_exp_sum' => function ($query) {
            $query->where('persuasion', true)->selectRaw('COALESCE(SUM(exp), 0)');
        }
    ])
    // 计算总分
    ->selectRaw('(COALESCE(charisma_exp_sum, 0) + COALESCE(persuasion_exp_sum, 0)) AS total_eval_score')
    ->orderByDesc('total_eval_score')
    ->first();

关键注意点

  • 移除了原代码中无逻辑的空with(['evaluations' => ...])写法,避免无意义预加载全量关联数据,减少内存占用
  • 所有求和逻辑都增加了COALESCE空值处理,避免用户在某个维度没有评估记录时,查询返回null导致总分计算异常、排序错位
  • 计算时增加exp IS NOT NULL判断,适配evaluations表中exp字段可空的结构设计
  • 两种写法的SQL执行效率基本一致,可根据自身代码习惯选择

内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 08:54:01