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

Laravel Raw Select返回重复值问题排查与解决

Laravel查询JSON列长度返回重复结果的问题解决

问题重现

我在模型中编写了测试方法,用于获取指定行JSON列的长度:

public function test(){
    return $this->select(DB::raw('JSON_LENGTH((SELECT comments FROM lab_evals WHERE id='.$this->id.'))'))->get();
}

在tinker中执行后,返回了包含重复对象的集合:

= Illuminate\Database\Eloquent\Collection {#7430
    all: [
      App\Models\LabEval {#7429
        JSON_LENGTH((SELECT comments FROM lab_evals WHERE id =50)): 2,
      },
      App\Models\LabEval {#7431
        JSON_LENGTH((SELECT comments FROM lab_evals WHERE id =50)): 2,
      },
    ],
  }

预期结果应该只包含一个对象。

原因分析

查看Laravel生成的原生SQL,找到了问题根源:

"select JSON_LENGTH((SELECT comments FROM lab_evals WHERE id=50)) from `lab_evals`"

这条SQL会遍历lab_evals表的每一行,每行都执行一次子查询计算JSON长度,所以表中有多少行,就会返回多少个重复结果。而正确的SQL应该是直接执行子查询获取单个值:

(SELECT JSON_LENGTH((SELECT comments from lab_evals WHERE id=50))); 

解决方法

改用DB::select()直接执行原生SQL,避免Laravel自动拼接from子句:

DB::select('SELECT JSON_LENGTH((SELECT comments from lab_evals WHERE id='.$this->id.'))')

补充:为避免SQL注入风险,推荐使用参数绑定的写法:

DB::select('SELECT JSON_LENGTH((SELECT comments from lab_evals WHERE id=?))', [$this->id])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:35:14