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

CodeIgniter科目成绩密集排名查询WHERE过滤失效问题

问题原因

两个核心问题导致排名错误:

  • SQL语句WHERE条件写法错误:条件两侧都用反引号包裹了同名字段,等价于字段=字段的恒真判断,完全没有使用传入的科目ID参数做过滤,因此查询返回了所有科目的成绩,导致跨科目混合排序。
  • 视图层排名逻辑未做去重处理,无法实现同分同名次的密集排名效果。
修复方案

模型层修改

修复SQL参数绑定逻辑,使用CodeIgniter的参数绑定机制传入科目ID,既实现科目过滤,也避免SQL注入风险,替换后的代码如下:

public function GetSubjectPosScores($exam_group_class_batch_exam_subject_id) 
{
    $sql = "
        SELECT `get_tot_score`
        FROM `exam_group_exam_results`
        WHERE `exam_group_class_batch_exam_subject_id` = ?
        ORDER BY `get_tot_score` DESC
    ";
    $query = $this->db->query($sql, [$exam_group_class_batch_exam_subject_id]);
    return $query->result();
}

控制器层

现有控制器仅做参数透传和模型调用,逻辑正确,无需修改。

视图层修改

补充分数去重、数组索引重置逻辑,实现标准密集排名(同分同排名,后续排名不空位),替换后的代码如下:

<?php
$scores2 = $CI->GetSubjectPosScores($exam_group_class_batch_exam_subject_id);
$scores = array_column($scores2, 'get_tot_score');
// 去重实现密集排名,重置索引避免键名不连续导致排名计算错误
$uniqueSortedScores = array_values(array_unique($scores));
$pos = array_search($exam_result_value->get_tot_score, $uniqueSortedScores);
$number = $pos + 1;
echo $CI->ordinal($number);
?>
修复后效果

修复后查询会先按传入的科目ID过滤成绩,仅在单个科目内做分数降序和排名计算,输出结果符合预期:

student_id | subject_id | get_tot_score | Position
---------------------------------------------------
 11        |   1        |   76          |  2nd
 12        |   1        |   90          |  1st
 28        |   6        |   89          |  1st
 30        |   6        |   70          |  2nd

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:36:28