You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL按分级Code字段分组生成树形结构,还是在JS中处理更合适?

问题解答

是否可以通过SQL直接生成目标嵌套JSON

可以实现,但高度依赖你使用的数据库类型:
当前主流支持递归CTE和JSON函数的数据库(PostgreSQL、MySQL 8.0+、Oracle 12c+等)都能完成这个需求,核心实现思路如下:

  • 第一步用递归CTE匹配每个节点的父节点:父节点Code为当前节点Code截掉最后1位,比如011的父节点为01,根节点(长度为1的Code)无父节点
  • 第二步通过数据库自带的JSON聚合函数(比如PostgreSQL的json_agg、MySQL的JSON_ARRAYAGG)递归拼接嵌套结构,最后输出整棵树的JSON

但SQL实现存在非常明显的短板:

  • 语法和数据库强绑定,换库就要完全重写
  • 层级不固定、深度较深的场景,SQL编写和调试难度非常高
  • 数据量大时递归查询性能远低于应用层遍历处理

更推荐的方案:JS(应用层)处理

绝大多数场景下把树形结构构造逻辑放在应用层用JS处理是更好的选择,实现简单、灵活好维护,示例代码如下:

function buildTree(data) {
  // 先把所有节点转成map,方便快速查找
  const nodeMap = {}
  const rootNodes = []
  data.forEach(item => {
    nodeMap[item.Code] = { ...item, children: [] }
  })
  // 遍历所有节点,挂载到对应的父节点下
  data.forEach(item => {
    const currentNode = nodeMap[item.Code]
    const parentCode = item.Code.slice(0, -1)
    // 没有父节点就是根节点
    if (!parentCode || !nodeMap[parentCode]) {
      rootNodes.push(currentNode)
    } else {
      nodeMap[parentCode].children.push(currentNode)
    }
  })
  return rootNodes
}

// 测试用,从数据库查询到的扁平数据
const flatData = [
  { Name: 'John', Code: '0' },
  { Name: 'Sam', Code: '01' },
  { Name: 'Jack', Code: '011' },
  { Name: 'Bill', Code: '02' },
  { Name: 'Parent', Code: '1' },
  { Name: 'Some1', Code: '11' },
  { Name: 'Some2', Code: '111' },
  { Name: 'Some3', Code: '112' },
  { Name: 'Some4', Code: '1111' }
]

console.log(buildTree(flatData))

这个实现不管层级多深都能正常生成嵌套结构,代码可读性高,调试和修改逻辑都非常方便,还和数据库选型完全解耦。

内容的提问来源于stack exchange,提问作者AlT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:09:01