无父ID场景下基于文件数据的递归自连接实现方法问询
无父ID场景下的递归自连接实现
当然可以实现递归自连接!虽然你的数据里没有显式的Parent ID,但Line字段里其实藏着层级关联的信息——我们只需要先把这些隐含的关系提取出来,生成临时的父级ID,之后就可以用常规的递归自连接逻辑来处理了。
第一步:解析Line字段,提取隐含的层级关系
你的Line字段是逗号分隔格式,从给出的例子来看,元素里包含了明确的层级标识:
- ID1、ID5的Line开头是数字,看起来像是组/顶级节点的标识
- ID2的Line开头是
*,属于另一种类型的顶级节点 - ID3、ID4的Line开头是两个空逗号(前两个元素为空),说明它们是上一个顶级节点的子级
我们需要把这些标识转化为明确的Parent ID,具体解析逻辑取决于你的业务规则,这里给两个常见场景的实现思路:
场景1:通过开头空逗号数量判断层级深度
如果Line开头的空逗号数量代表层级(比如0个空逗号是顶级,2个是二级子节点),可以用窗口函数匹配父节点:
-- 先拆分解析Line,计算层级深度 WITH parsed_data AS ( SELECT ID, Line, -- 计算开头连续空逗号的数量(层级) LEN(Line) - LEN(LTRIM(REPLACE(Line, ',', ' '))) AS leading_commas FROM your_table ), -- 生成Parent ID hierarchy AS ( SELECT ID, Line, leading_commas, -- 找到上一个层级比当前小1的节点作为父节点 MAX(CASE WHEN leading_commas = current.leading_commas - 1 THEN ID END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS Parent_ID FROM parsed_data current ) -- 递归自连接查询 WITH recursive_tree AS ( -- 锚点:顶级节点(层级为0) SELECT ID, Line, Parent_ID, 0 AS level FROM hierarchy WHERE leading_commas = 0 UNION ALL -- 递归:关联子节点与父节点 SELECT child.ID, child.Line, child.Parent_ID, parent.level + 1 FROM hierarchy child JOIN recursive_tree parent ON child.Parent_ID = parent.ID ) SELECT * FROM recursive_tree;
场景2:通过Line第一个元素的标识分组
如果Line的第一个元素是组标识(比如ID1的3),其他节点属于最近的这个组,可以这样处理:
-- 解析Line的第一个元素 WITH parsed_data AS ( SELECT ID, Line, -- 提取Line第一个元素 LEFT(Line, CHARINDEX(',', Line) - 1) AS group_id FROM your_table ), -- 生成Parent ID:每个子节点关联最近的组节点 hierarchy AS ( SELECT ID, Line, group_id, -- 找到最近的组节点(第一个元素为数字的节点)作为父节点 MAX(CASE WHEN ISNUMERIC(group_id) = 1 THEN ID END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS Parent_ID FROM parsed_data ) -- 递归自连接 WITH recursive_tree AS ( -- 锚点:所有组节点 SELECT ID, Line, Parent_ID, 0 AS level FROM hierarchy WHERE ISNUMERIC(group_id) = 1 UNION ALL -- 递归:关联组内子节点 SELECT child.ID, child.Line, child.Parent_ID, parent.level + 1 FROM hierarchy child JOIN recursive_tree parent ON child.Parent_ID = parent.ID WHERE ISNUMERIC(child.group_id) != 1 ) SELECT * FROM recursive_tree;
关键总结
核心逻辑就是先从Line字段里挖掘出父节点和子节点的对应关系,生成临时的Parent ID字段,之后的递归自连接就和常规带Parent ID的层级数据处理完全一致了。如果你的Line字段有其他特殊规则,只需要调整解析Parent ID的逻辑即可。
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

