使用Union查询获取学生学期总分后无法正确在表格中展示结果的问题求助
问题分析与解决方案
看起来你在处理UNION查询结果的表格展示时踩了几个典型的坑,我来帮你逐一拆解并解决:
1. SQL查询的字段缺失问题
首先看你的查询语句,三个SELECT里都没有包含subject_id字段,但你在视图里尝试调用$CI->GetSubjectNameWithID($totvalue->subject_id)获取科目名称——这会直接导致找不到该字段的错误。你需要在每个SELECT中补充对应的subject_id,并统一别名,确保UNION后的结果集能拿到这个字段:
SELECT mp.id, mp.student_id, mp.class_id, mp.section_id, mp.subject_id, mp.ft_ca1, mp.ft_ca2, mp.ft_ca3, mp.ft_ca4, mp.ft_ca5, mp.ft_ca6, mp.ft_project, mp.ft_affective, mp.ft_psychomotor, mp.ft_exam, mp.ft_tot_score as total, mp.created_at, mp.modified_at FROM ftscores_primary mp WHERE mp.class_id = 7 AND mp.student_id = 23 AND mp.section_id = 1 AND mp.subject_id = 8 AND mp.session_id = 16 UNION SELECT st.id, st.student_id, st.class_id, st.section_id, st.subject_id, st.ca1, st.ca2, st.ca3, st.ca4, st.ca5, st.ca6, st.project, st.affective, st.psychomotor, st.exam, st.tot_score, st.created_at, st.modified_at FROM scores_primary st WHERE st.class_id = 7 AND st.student_id = 23 AND st.section_id = 1 AND st.subject_id = 8 AND st.session_id = 16 UNION SELECT tt.id, tt.student_id, tt.class_id, tt.section_id, tt.subject_id, tt.h_ca1, tt.h_ca2, tt.h_ca3, tt.h_ca4, tt.h_ca5, tt.h_ca6, tt.h_project, tt.h_affective, tt.h_psychomotor, tt.h_exam, tt.h_tot_score, tt.created_at, tt.modified_at FROM hscores_primary tt WHERE tt.class_id = 7 AND tt.student_id = 23 AND tt.section_id = 1 AND tt.subject_id = 8 AND tt.session_id = 16
2. 数组访问的逻辑错误
你用$query->result_array()获取的是关联数组的集合,不是对象,所以:
- 不能用
$totvalue->subject_id这种对象属性的访问方式,要改成数组下标访问$totvalue['subject_id'] - 你的
foreach循环逻辑有误:$totScores是包含3个元素的数组(分别对应三个学期),foreach ($totScores as $totvalue)会循环3次,每次的$totvalue是单个学期的完整数据,而不是包含三个学期的数组。所以$totvalue[0]['total']这种写法完全错误,直接用$totvalue['total']就能拿到当前循环的这个学期的总分。
3. 表格展示的逻辑修正
根据你想汇总三个学期总分到一行的需求,不需要用foreach循环,直接访问$totScores的下标即可:
<tr> <!-- 三个学期的subject_id是同一个,取第一个即可 --> <td><?php echo $CI->GetSubjectNameWithID($totScores[0]['subject_id']); ?></td> <td><?php echo $totScores[0]['total']; ?></td> <!-- 第一学期总分 --> <td><?php echo $totScores[1]['total']; ?></td> <!-- 第二学期总分 --> <td><?php echo $totScores[2]['total']; ?></td> <!-- 第三学期总分 --> </tr>
如果后续需要每个学期单独占一行展示,再用foreach循环:
<?php foreach ($totScores as $totvalue) { ?> <tr> <td><?php echo $CI->GetSubjectNameWithID($totvalue['subject_id']); ?></td> <td><?php echo $totvalue['total']; ?></td> </tr> <?php } ?>
额外优化建议
可以给每个UNION的结果加上一个学期标识,方便后续区分:
SELECT ..., '第一学期' as semester, ... FROM ftscores_primary mp WHERE ... UNION SELECT ..., '第二学期' as semester, ... FROM scores_primary st WHERE ... UNION SELECT ..., '第三学期' as semester, ... FROM hscores_primary tt WHERE ...
这样在展示时还能明确标注每个分数对应的学期,结果更直观。
内容的提问来源于stack exchange,提问作者KasimaEse




