PHP/MySQLi隐藏重复行:实现单MATIERE对应多NOTE_DEVOIR展示
解决校园管理项目中MATIERE重复展示的问题
嘿,这个问题我之前帮不少开发者处理过,咱们一步步来搞定它~核心需求很明确:不改动数据库里的重复数据,只在PHP层面把重复的MATIERE合并,展示每个唯一MATIERE对应的所有NOTE_DEVOIR。下面是具体实现步骤:
1. 优化数据库查询,获取完整关联数据
首先得确保SQL能拿到所有需要的字段,通过JOIN关联三张表,同时按MATIERE的ID排序,方便后续PHP分组处理。示例SQL(你可以根据实际表结构调整字段名):
SELECT m.id AS matiere_id, m.nom AS matiere_nom, nd.* FROM NOTE_DEVOIR nd JOIN MODULE_DEVOIR md ON nd.module_devoir_id = md.id JOIN MATIERE m ON md.matiere_id = m.id ORDER BY m.id, nd.id;
2. PHP层面整理数据,按MATIERE分组
拿到查询结果后,我们用数组把数据重新组织成「唯一MATIERE对应多个NOTE_DEVOIR」的结构,用MATIERE的ID作为数组键(保证唯一性):
// 假设$pdo是你的数据库连接对象 $query = "SELECT m.id AS matiere_id, m.nom AS matiere_nom, nd.* FROM NOTE_DEVOIR nd JOIN MODULE_DEVOIR md ON nd.module_devoir_id = md.id JOIN MATIERE m ON md.matiere_id = m.id ORDER BY m.id, nd.id"; $stmt = $pdo->prepare($query); $stmt->execute(); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); // 初始化分组数组 $matiereNotes = []; foreach ($results as $row) { $matiereId = $row['matiere_id']; // 如果该MATIERE还没加入数组,先初始化基础信息 if (!isset($matiereNotes[$matiereId])) { $matiereNotes[$matiereId] = [ 'id' => $matiereId, 'nom' => $row['matiere_nom'], 'notes_devoir' => [] ]; } // 把当前的NOTE_DEVOIR加入对应MATIERE的列表 $matiereNotes[$matiereId]['notes_devoir'][] = [ 'id' => $row['id'], 'titre' => $row['titre'], // 替换成你的NOTE_DEVOIR实际字段 'note' => $row['note'], // 其他需要展示的字段都可以加在这里 ]; } // 转成索引数组(可选,方便前端遍历) $matiereNotes = array_values($matiereNotes);
3. 前端展示,隐藏重复MATIERE行
现在$matiereNotes里已经是整理好的结构了,直接在HTML里遍历展示即可,每个MATIERE只显示一次,下面列出它的所有作业记录:
foreach ($matiereNotes as $matiere) { echo "<h3>{$matiere['nom']}</h3>"; echo "<div class='note-list'>"; foreach ($matiere['notes_devoir'] as $note) { echo "<p>作业标题: {$note['titre']} | 分数: {$note['note']}</p>"; } echo "</div>"; }
额外小提示
- 优先用MATIERE的ID作为分组依据,比用名称更可靠(避免重名导致分组错误)。
- 如果MATIERE有更多字段需要展示,只需要在初始化
$matiereNotes[$matiereId]时把字段加进去就行。 - 要是需要分页,直接在SQL里加
LIMIT和OFFSET就行,分组逻辑不会受影响。
这样处理后,数据库里的重复数据完全保留,只是展示时合并了同一个MATIERE的记录,完美满足你的需求~
内容的提问来源于stack exchange,提问作者medo100000S
相关产品推荐
相关产品推荐

