如何用Laravel Eloquent仅统计用户每题首次答题的正确得分总和
解决方案:只统计每个问题首次作答的得分
嘿,这个需求其实用Laravel Eloquent的子查询+分组就能轻松实现,核心思路就是先筛选出用户每个问题的第一条作答记录,再对这些记录的correct值求和。我给你两种常用的实现方式,你可以根据自己的数据库结构选:
方式一:利用自增ID判断首次作答(推荐,性能更好)
如果你的testsresult表用自增ID(id字段)来记录顺序,最早的作答记录ID最小,那可以这么写:
$total_score = User::find($user->id)->testsresult() ->whereIn('id', function($query) { // 子查询:按question_id分组,取每个问题的第一条记录ID(最小ID) $query->selectRaw('MIN(id)') ->from('testsresults') // 这里注意表名,要和你的实际表名一致,比如可能是testsresults ->whereColumn('user_id', 'testsresults.user_id') ->groupBy('question_id'); }) ->sum('correct');
代码解释:
- 子查询部分:按
question_id分组,对每个分组取最小的id(也就是该用户对这个问题的第一次作答记录) - 外层查询只保留这些ID对应的记录,最后对
correct字段求和
方式二:利用创建时间判断首次作答
如果你的表没有自增ID,或者更依赖created_at字段来判断作答顺序,可以用这种方式:
$total_score = User::find($user->id)->testsresult() ->whereIn('id', function($query) { $query->select('id') ->from('testsresults as tr') ->whereColumn('tr.user_id', 'testsresults.user_id') // 筛选出每个问题中创建时间最早的记录 ->whereRaw('tr.created_at = (SELECT MIN(created_at) FROM testsresults WHERE user_id = tr.user_id AND question_id = tr.question_id)'); }) ->sum('correct');
注意事项:
- 请确保你的
testsresult表包含question_id字段(用来标识同一个问题),以及能判断作答顺序的字段(id或created_at) - 表名要和实际数据库一致,比如如果你的表是
testsresults(复数),记得修改子查询里的表名
内容的提问来源于stack exchange,提问作者Hassan
相关产品推荐
相关产品推荐

