CodeIgniter按科目查询成绩最高分并在视图动态输出的问题
解决方案
现有代码问题
你写的MVC代码存在两处错误:
- Model层调用
select_max方式错误:CodeIgniter的select_max方法仅支持传入单个原生字段名,不支持直接传入计算表达式;且get()方法内填写的表名错误,你写的max_score是字段别名,实际查询表应为exam_results - 逻辑设计不符合MVC规范:不应该在视图中调用Controller方法,正确流程是Controller接收请求后,完成所有数据查询、组装,再把成品数据传给视图渲染,视图层只负责输出HTML,不执行业务逻辑/数据库查询。
修正后的标准MVC实现
Model层修正
public function GetMaxScore($subject_id) { // 第二个参数传false,禁止CI自动转义计算表达式 $this->db->select("MAX(get_ca1 + get_ca2 + get_exam) AS max_score", false); $this->db->where('subject_id', $subject_id); $result = $this->db->get('exam_results')->row(); return $result ? $result->max_score : 0; } // 推荐用这个单查询方法,性能更高,不需要循环查最高分 public function getStudentScoreWithHighest($student_id) { $sql = "SELECT CASE er.subject_id WHEN 1 THEN 'Maths' WHEN 2 THEN 'Eng' END AS subject, er.get_ca1 ca1, er.get_ca2 ca2, er.get_exam exam, sub_max.max_score highest FROM exam_results er INNER JOIN ( SELECT subject_id, MAX(get_ca1 + get_ca2 + get_exam) max_score FROM exam_results GROUP BY subject_id ) sub_max ON er.subject_id = sub_max.subject_id WHERE er.student_id = ?"; return $this->db->query($sql, [$student_id])->result_array(); }
Controller层实现
public function showStudentScore($student_id) { // 直接调用优化后的查询方法,一次拿到所有需要的数据 $data['score_list'] = $this->examgroupstudent_model->getStudentScoreWithHighest($student_id); $this->load->view('score_table', $data); }
视图层(score_table.php)
直接遍历传入的数据渲染表格即可,不需要写任何查询逻辑:
<table> <thead> <tr> <th>subject</th> <th>ca1</th> <th>ca2</th> <th>exam</th> <th>highest</th> </tr> </thead> <tbody> <?php foreach ($score_list as $row): ?> <tr> <td><?= $row['subject'] ?></td> <td><?= $row['ca1'] ?></td> <td><?= $row['ca2'] ?></td> <td><?= $row['exam'] ?></td> <td><?= $row['highest'] ?></td> </tr> <?php endforeach; ?> </tbody> </table>
传入student_id=103时,输出的表格完全符合你的需求。
视图直接写查询的实现方式(不推荐,违反MVC规范)
如果你坚持在视图中直接写查询,只需要在循环每行成绩时,把当前行的subject_id动态传入查询条件即可,不要硬编码ID:
<!-- 假设$row是当前循环的成绩行数据 --> <td> <?php $current_subid = $row['subject_id']; // 用参数绑定传值,避免SQL注入 $query = $this->db->query("SELECT MAX(`get_ca1`+`get_ca2`+`get_exam`) AS max_score FROM exam_results WHERE `subject_id`=?", [$current_subid]); $highscore = $query->row(); echo $highscore->max_score; ?> </td>
注意:这种写法会在表格每一行都执行一次数据库查询,数据量大时性能很差,仅适合临时调试使用。
内容的提问来源于stack exchange,提问作者MaryPebbles
相关产品推荐
相关产品推荐

