MySQL一对多关系中如何查询唯一分类并关联显示所属企业
解决MySQL查询中分类仅显示一次、下属企业列于其下的问题
嘿,我明白你想要的效果——让每个分类只显示一次,下面列出它旗下的所有企业,而不是每条企业记录都重复输出一遍分类名称。咱们可以从两个方向来解决这个问题,看你更适配哪种场景:
方法1:数据库层面用聚合函数拼接企业列表
如果只需要把同分类下的企业名合并成一个字符串展示,用GROUP_CONCAT就能快速实现。修改后的SQL语句如下:
SELECT category.id AS category_id, category.category_name, GROUP_CONCAT(company.company_name SEPARATOR ', ') AS company_list FROM company INNER JOIN category ON company.category_id = category.id GROUP BY category.id, category.category_name;
说明:
GROUP BY category.id, category.category_name确保每个分类只生成一行结果GROUP_CONCAT会把同分类下的所有企业名拼接成一个字符串,默认用逗号分隔,你可以通过SEPARATOR指定其他分隔符(比如SEPARATOR '\n'换成换行,不过最终显示效果要看应用层的渲染逻辑)- 查询结果会是这样的结构:
category_id category_name company_list 1 School Dolly, Abbey scaffold, AP 2 Art Blue script
方法2:应用层遍历结果集实现层级展示
如果需要对每个企业单独做自定义操作(比如给企业名加链接、显示更多企业信息),更推荐在应用代码层面处理。步骤如下:
第一步:调整SQL查询,按分类排序
先把所有数据按分类ID排序,确保同分类的企业连在一起:
SELECT company.id, company.company_name, category.id AS category_id, category.category_name FROM company INNER JOIN category ON company.category_id = category.id ORDER BY category.id, company.company_name;
第二步:在应用代码中遍历处理
以PHP为例(假设用PDO获取结果集),通过记录上一个分类ID来控制分类名称的输出时机:
$prevCategoryId = null; // 假设$stmt是已经执行过的查询语句对象 foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { // 当分类ID变化时,输出新的分类标题 if ($row['category_id'] !== $prevCategoryId) { // 关闭上一个分类的列表(如果存在) if ($prevCategoryId !== null) { echo "</ul>"; } echo "<h3>" . htmlspecialchars($row['category_name']) . "</h3>"; echo "<ul>"; $prevCategoryId = $row['category_id']; } // 输出当前企业 echo "<li>" . htmlspecialchars($row['company_name']) . "</li>"; } // 关闭最后一个分类的列表 if ($prevCategoryId !== null) { echo "</ul>"; }
说明:
这种方式的优势是灵活性更高,你可以轻松扩展每个企业的展示内容,比如添加企业ID跳转、联系方式等。其他语言(Python、Java等)的逻辑类似,核心都是通过追踪分类ID的变化来控制层级输出。
内容的提问来源于stack exchange,提问作者show4real
相关产品推荐
相关产品推荐

