Laravel foreach循环调用getSubtitle始终返回methodolgy表首条记录问题
问题原因
你的代码核心错误出在having条件的参数写法上:
你在CASE WHEN语句中设置不匹配时返回的值是无单引号的字符串bos,但having条件里写的是->having("sonuc","!=","'bos'"),第三个参数额外包裹了单引号,实际参与比较的值是带单引号的'bos',这就导致所有行的sonuc字段都满足「不等于'bos'」的条件,所有记录都会被返回,最终按id升序取第一条就永远拿到表的首条记录。
另外你直接把$score拼接到selectRaw中还存在两个隐患:
- 没有参数绑定,存在SQL注入风险
- 如果
$score是字符串类型没有包裹引号,会导致SQL逻辑异常
解决方案
最优方案:调整查询逻辑,删除不必要的CASE WHEN
你要实现的「找到$score落在start和end区间内的记录」完全可以通过普通where条件实现,写法更简洁、性能更高、也不会出现拼接错误:
function getSubtitle($id,$score){ $surveys = DB::table("methodolgy") ->where("main_survey",$id) ->where('start', '<=', $score) ->where('end', '>=', $score) ->orderBy("id","ASC") ->first(); return isset($surveys->message) ? $surveys->message : "Activity Not Found"; }
如果你坚持用原有CASE WHEN写法
只需要去掉having条件中第三个参数的单引号即可:
->having("sonuc","!=","bos")
额外优化建议
你在循环中重复调用了两次SurveyController::getScore($s->id),可以将结果存入变量复用,减少不必要的性能开销:
foreach($surveys AS $s) { $score = SurveyController::getScore($s->id); $surList[$s->cat][] = [ "id" => $s->id, "title" => $s->title, "score" => $score, "subtitle" => SurveyController::getSubtitle($s->id, $score) ]; }
内容的提问来源于stack exchange,提问作者Eren GELGEC
相关产品推荐
相关产品推荐

