PHP合并MySQL查询结果生成按人员分组的嵌套结构JSON数组
解答
可行性结论
该需求完全可实现,无需修改SQL查询的返回字段,仅需在PHP层遍历结果集时做按姓名维度的分组聚合,即可完成嵌套结构重构。
注:你给出的期望JSON存在语法错误:JSON规范中数组类型(
[])仅支持数字索引,存储技能名:分数这类字符串键值对必须使用对象类型({}),最终输出的合法JSON会对该部分做修正。
实现逻辑
处理单行分散记录的核心是用临时关联数组做分组映射:
- 临时数组的键使用人员姓名,值为对应人员的最终结构对象
- 遍历每一行查询结果时,先判断临时数组中是否已存在当前人员的条目:
- 不存在则初始化条目,写入name字段,同时挂载空的skills容器
- 已存在则直接将当前行的技能名、分数作为键值对追加到对应人员的skills容器中
- 遍历结束后,丢弃临时数组的姓名键,转为普通索引数组即可输出符合要求的JSON
修改后的代码
注意:你原有代码中的SQL语句截断缺失了FROM和多表JOIN关联逻辑,请根据实际表关系补全后再使用,否则SQL会执行报错。
function getList(){ $sql = 'SELECT DISTINCT `person`.`person_name` as name, `skill`.`skill_name` as skill,`skill_linker`.`skill_score` -- 以下为需要你补全的表关联部分示例,请替换为实际业务逻辑 FROM person INNER JOIN skill_linker ON person.person_id = skill_linker.person_id INNER JOIN skill ON skill_linker.skill_id = skill.skill_id '; $result = $GLOBALS['conn']->query($sql); if ($result->num_rows > 0) { $groupedData = []; while($row = $result->fetch_assoc()) { $personName = $row['name']; // 初始化未收录的人员结构 if (!isset($groupedData[$personName])) { $groupedData[$personName] = [ 'name' => $personName, 'skills' => [] ]; } // 追加技能分数键值对,分数转为整数类型 $groupedData[$personName]['skills'][$row['skill']] = intval($row['skill_score']); } // 重置数组为索引数组,输出JSON(加JSON_UNESCAPED_UNICODE避免中文转码) echo json_encode(array_values($groupedData), JSON_UNESCAPED_UNICODE); } }
最终输出的合法JSON结构
[ { "name": "Bob Sun", "skills": { "Dancing": 3, "Surfing": 2, "Swimming": 5 } }, { "name": "Joe Steel", "skills": { "Eating": 2, "Cooking": 3 } } ]
如果你需要skills字段返回数组类型,只能将每个技能调整为{"skillName":"Dancing", "score":3}格式的对象数组,和你要求的skill:skill_score键值对结构不兼容。
内容的提问来源于stack exchange,提问作者newbieJ
相关产品推荐
相关产品推荐

