如何用SQL WHILE循环获取人员的最终关联父级
使用SQL WHILE循环获取每个节点的最终关联父级
原始表结构与数据
| Person | Related Parent |
|---|---|
| A | B |
| B | C |
| C | NULL |
| D | B |
| E | NULL |
预期结果
| Person | Ultimate Related Parent |
|---|---|
| A | C |
| B | C |
| C | NULL |
| D | C |
| E | NULL |
实现代码(以SQL Server为例)
-- 创建临时表存储中间结果,保留原始Person和当前父级 CREATE TABLE #TempHierarchy ( Person VARCHAR(10) PRIMARY KEY, CurrentParent VARCHAR(10) ) -- 从原始表导入数据 INSERT INTO #TempHierarchy (Person, CurrentParent) SELECT Person, [Related Parent] FROM YourOriginalTableName; -- 声明变量记录每次循环的更新行数 DECLARE @UpdatedRows INT = 1; -- WHILE循环:只要有更新就继续执行 WHILE @UpdatedRows > 0 BEGIN -- 更新当前父级为父节点的最终父级 UPDATE th SET th.CurrentParent = th2.CurrentParent FROM #TempHierarchy th JOIN #TempHierarchy th2 ON th.CurrentParent = th2.Person WHERE th.CurrentParent IS NOT NULL AND th2.CurrentParent IS NOT NULL -- 获取本次更新的行数,判断是否继续循环 SET @UpdatedRows = @@ROWCOUNT; END -- 查询最终结果 SELECT Person, CurrentParent AS [Ultimate Related Parent] FROM #TempHierarchy; -- 清理临时表 DROP TABLE #TempHierarchy;
代码说明
- 临时表初始化:创建临时表避免直接修改原始数据,同时方便循环中反复更新父级信息。
- 循环启动条件:
@UpdatedRows初始设为1,确保第一次循环能正常执行。 - 核心更新逻辑:通过自连接,把每个节点的当前父级替换成其父节点的当前父级——直到某个节点的父级是NULL(即最终父级),就不再更新它。
- 循环终止条件:当某次循环没有更新任何行(
@UpdatedRows=0),说明所有可追溯的节点都已经找到最终父级,循环结束。
注意事项
- 把代码中的
YourOriginalTableName替换成你实际的表名。 - 如果是MySQL数据库,语法略有不同:临时表命名去掉
#,@@ROWCOUNT替换为ROW_COUNT(),其他逻辑一致。 - 确保数据没有循环引用(比如A→B→A),否则循环会无限执行。
内容的提问来源于stack exchange,提问作者user15170185
相关产品推荐
相关产品推荐

