PHP查询中隐藏重复行:实现单matiere对应多devoir展示
解决Matiere关联Devoir时重复显示的问题
这是个非常常见的一对多关联数据展示问题,核心是在PHP层面对查询结果做分组处理——既保留所有原始数据,又能实现只显示一次Matiere、下方列出所有关联Devoir的效果。下面是具体实现步骤:
1. 先获取原始查询结果
假设你已经通过SQL(比如LEFT JOIN)拿到了包含Matiere和对应Devoir的原始数据,示例如下:
// 示例:PDO查询返回的关联数组 $pdo = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'pass'); $stmt = $pdo->query("SELECT m.id as matiere_id, m.nom as matiere_nom, d.id as devoir_id, d.titre as devoir_titre FROM matiere m LEFT JOIN devoir d ON m.id = d.matiere_id"); $rawResults = $stmt->fetchAll(PDO::FETCH_ASSOC);
这个查询会返回多条重复Matiere的记录,每个Devoir对应一条。
2. 对数据进行分组处理
我们以Matiere的唯一标识(比如matiere_id)为键,把同一个Matiere的所有Devoir收集到一起:
$groupedMatieres = []; foreach ($rawResults as $item) { $matiereId = $item['matiere_id']; // 如果当前Matiere还没加入分组数组,先初始化它的基础信息 if (!isset($groupedMatieres[$matiereId])) { $groupedMatieres[$matiereId] = [ 'id' => $matiereId, 'nom' => $item['matiere_nom'], 'devoirs' => [] // 用来存储该Matiere下的所有Devoir ]; } // 把当前Devoir添加到对应Matiere的Devoir列表中(处理无Devoir的情况) if (!empty($item['devoir_id'])) { $groupedMatieres[$matiereId]['devoirs'][] = [ 'id' => $item['devoir_id'], 'titre' => $item['devoir_titre'] // 这里可以添加Devoir的其他字段,比如截止日期、描述等 ]; } } // 可选:将关联数组转为索引数组,方便后续遍历 $groupedMatieres = array_values($groupedMatieres);
3. 渲染页面时控制显示逻辑
现在分组后的数据结构是每个Matiere对应一个Devoir数组,渲染时只需显示一次Matiere,再遍历它的Devoir列表即可:
foreach ($groupedMatieres as $matiere) { // 只显示一次Matiere信息 echo "<div class='matiere-card'>"; echo "<h2>{$matiere['nom']}</h2>"; // 显示该Matiere下的所有Devoir if (!empty($matiere['devoirs'])) { echo "<ul class='devoir-list'>"; foreach ($matiere['devoirs'] as $devoir) { echo "<li> <span>{$devoir['titre']}</span> <a href='edit_devoir.php?id={$devoir['id']}'>编辑</a> </li>"; } echo "</ul>"; } else { echo "<p>暂无作业</p>"; } echo "</div>"; }
补充说明
- 这个方法完全保留了所有原始数据,只是在PHP层面做了分组,不会丢失任何Devoir信息
- 如果你的场景不需要单独操作每个Devoir,也可以用SQL的
GROUP_CONCAT把Devoir合并成字符串,但灵活性远不如PHP分组 - 确保分组时用的是Matiere的唯一标识(比如主键ID),避免不同Matiere被错误合并
内容的提问来源于stack exchange,提问作者medo10S0S
相关产品推荐
相关产品推荐

