如何关联分类与子分类数据库实现对应子分类数据查询
实现方法
关联分类和子分类不需要嵌套多层循环逐行比对,有两种成熟实现方式,按需选择即可。
方案1:PHP侧数据分组(适配现有代码,改动最小)
你已经拿到了分类表的$topics结果集,只需要额外查询一次全量子分类数据,先把子分类按parent_id归组成键值对结构,遍历分类时直接按分类ID取对应子分类列表即可。
<?php // 假设你已经通过原有逻辑拿到了分类数据 $topics // 1. 查询全部子分类,注意right是SQL保留字,必须加反引号 // $subcategories = $db->query("SELECT id, parent_id, `right` FROM subcategory")->fetchAll(PDO::FETCH_ASSOC); // 2. 子分类按父ID分组 $groupedSub = []; foreach ($subcategories as $sub) { $groupedSub[$sub['parent_id']][] = $sub; } ?> <!-- 原有分类遍历逻辑改造 --> <table> <?php foreach ($topics as $topic): ?> <tr> <td><?php echo htmlspecialchars($topic['category']); ?></td> <td> <?php if (isset($groupedSub[$topic['id']])): ?> <ul> <?php foreach ($groupedSub[$topic['id']] as $subItem): ?> <li><?php echo htmlspecialchars($subItem['right']); ?></li> <?php endforeach; ?> </ul> <?php else: ?> 暂无子分类 <?php endif; ?> </td> </tr> <?php endforeach; ?> </table>
方案2:SQL联表查询(性能更优,推荐)
直接通过LEFT JOIN在SQL层完成两张表的关联,一次查询拿到所有需要的数据,再按分类维度简单重组即可,查询效率比两次单独查询更高,给subcategory表的parent_id字段加索引后速度还能进一步提升。
<?php // 联表查询语句 $sql = "SELECT c.id AS cid, c.category, s.id AS sid, s.`right` AS sub_name FROM category c LEFT JOIN subcategory s ON c.id = s.parent_id ORDER BY c.id ASC, s.id ASC"; // $rawList = $db->query($sql)->fetchAll(PDO::FETCH_ASSOC); // 按分类维度重组数据 $categoryList = []; foreach ($rawList as $row) { $cid = $row['cid']; if (!isset($categoryList[$cid])) { $categoryList[$cid] = [ 'name' => $row['category'], 'subs' => [] ]; } // 过滤没有子分类的空关联记录 if (!empty($row['sid'])) { $categoryList[$cid]['subs'][] = $row['sub_name']; } } ?> <!-- 遍历输出 --> <table> <?php foreach ($categoryList as $cat): ?> <tr> <td><?php echo htmlspecialchars($cat['name']); ?></td> <td> <?php if (!empty($cat['subs'])): ?> <ul> <?php foreach ($cat['subs'] as $subName): ?> <li><?php echo htmlspecialchars($subName); ?></li> <?php endforeach; ?> </ul> <?php else: ?> 暂无子分类 <?php endif; ?> </td> </tr> <?php endforeach; ?> </table>
注意事项
- 禁止在遍历分类的循环内单独查询当前分类的子分类,会产生N+1查询问题,数据量稍大时性能会急剧下降
- 所有数据库查询里涉及
right字段的地方,必须用反引号包裹,否则会报SQL语法错误 - 输出数据库存储的文本时统一用
htmlspecialchars()转义,避免XSS安全漏洞
内容的提问来源于stack exchange,提问作者IchBinDuck
相关产品推荐
相关产品推荐

