sql - 查找 SQL 表中的最低递归
问题描述
我需要获取层次结构数据中的最低父级。我在获取最低父 ID 时遇到问题。请参阅下面的查询和预期结果。对此的任何帮助表示赞赏。
CREATE TABLE #Modules ([ModuleId] INT, [ModuleName] VARCHAR(50) NOT NULL, [ParentId] INT NULL)
INSERT INTO #Modules
SELECT 1, 'Master', NULL
UNION ALL SELECT 2, 'UsersGroup2', 1
UNION ALL SELECT 3, 'UsersGroup3', 2
UNION ALL SELECT 4, 'UsersGroup4', 3
UNION ALL SELECT 5, 'UsersGroup5', 4
UNION ALL SELECT 6, 'UsersGroup6', 5
UNION ALL SELECT 7, 'UsersGroup7', 5
UNION ALL SELECT 8, 'UsersGroup8', NULL
UNION ALL SELECT 9, 'UsersGroup9', NULL
UNION ALL SELECT 10, 'UsersGroup10', 9
UNION ALL SELECT 11, 'UsersGroup11', 10
UNION ALL SELECT 12, 'UsersGroup12', 11
UNION ALL SELECT 14, 'UsersGroup14', 12
UNION ALL SELECT 15, 'UsersGroup15', 9
;WITH CTE AS (SELECT 1 AS [Level], [ModuleId],
[ModuleName] AS [GrandParent], [ModuleName], [ParentId]
FROM #Modules
WHERE [ParentId] IS NULL
UNION ALL SELECT cycle.[Level] + 1, base.[ModuleId],
cycle.[GrandParent], base.[ModuleName], base.[ParentId]
FROM #Modules base
INNER JOIN CTE cycle ON cycle.[ModuleId] = base.[ParentId])
SELECT CTE.ModuleId, CTE.ParentId AS GrandParentId, COALESCE(NULLIF([GrandParent],[ModuleName])+'-->'+[ModuleName],[ModuleName]) AS [ModuleName]
FROM CTE
DROP TABLE #Modules
结果:
ModuleId GrandParentId ModuleName
1 NULL Master
8 NULL UsersGroup8
9 NULL UsersGroup9
10 9 UsersGroup9-->UsersGroup10
15 9 UsersGroup9-->UsersGroup15
11 9 UsersGroup9-->UsersGroup11
12 9 UsersGroup9-->UsersGroup12
14 9 UsersGroup9-->UsersGroup14
2 1 Master-->UsersGroup2
3 1 Master-->UsersGroup3
4 1 Master-->UsersGroup4
5 1 Master-->UsersGroup5
6 1 Master-->UsersGroup6
7 1 Master-->UsersGroup7
解决方案
您在递归 CTE 中将 ParentID 作为 GrandParent 返回。当您重新加入 CTE 以获得所有级别时,这种情况正在发生变化。
如果您在顶层也定义了 GrandParentID 字段并在 CTE 的第二层中引用它,您将得到答案:
with data1 as(
SELECT 1 [ModuleId], 'Master' [ModuleName], NULL [ParentId]
UNION ALL SELECT 2, 'UsersGroup2', 1
UNION ALL SELECT 3, 'UsersGroup3', 2
UNION ALL SELECT 4, 'UsersGroup4', 3
UNION ALL SELECT 5, 'UsersGroup5', 4
UNION ALL SELECT 6, 'UsersGroup6', 5
UNION ALL SELECT 7, 'UsersGroup7', 5
UNION ALL SELECT 8, 'UsersGroup8', NULL
UNION ALL SELECT 9, 'UsersGroup9', NULL
UNION ALL SELECT 10, 'UsersGroup10', 9
UNION ALL SELECT 11, 'UsersGroup11', 10
UNION ALL SELECT 12, 'UsersGroup12', 11
UNION ALL SELECT 14, 'UsersGroup14', 12
UNION ALL SELECT 15, 'UsersGroup15', 9
)
, CTE AS (SELECT 1 AS [Level], [ModuleId], [ModuleId] GrandParentID ,
[ModuleName] AS [GrandParent], [ModuleName], [ParentId]
FROM data1
WHERE [ParentId] IS NULL
UNION ALL
SELECT cycle.[Level] + 1,
base.[ModuleId],
cycle.GrandParentID,
cycle.[GrandParent],
base.[ModuleName],
base.[ParentId]
FROM data1 base
INNER JOIN CTE cycle ON cycle.[ModuleId] = base.[ParentId])
SELECT CTE.ModuleId, GrandParentId,COALESCE(NULLIF([GrandParent],[ModuleName])+'-->'+[ModuleName],[ModuleName]) AS [ModuleName]
FROM CTE
或以您的格式:
WITH CTE AS (SELECT 1 AS [Level], [ModuleId], [ModuleId] GrandParentID,
[ModuleName] AS [GrandParent], [ModuleName], [ParentId]
FROM #Modules
WHERE [ParentId] IS NULL
UNION ALL SELECT cycle.[Level] + 1, base.[ModuleId],
cycle.[GrandParent], base.[ModuleName], base.[ParentId]
FROM #Modules base
INNER JOIN CTE cycle ON cycle.[ModuleId] = base.[ParentId])
SELECT CTE.ModuleId, CTE.GrandParentId, COALESCE(NULLIF([GrandParent],[ModuleName])+'-->'+[ModuleName],[ModuleName]) AS [ModuleName]
FROM CTE
推荐阅读
- spring-boot - 在Spingboot中如何确定一个consumer group中的consumer个数?
- python - 在 python 中使用 Tweepy 的正则表达式错误
- php - 使用 PHP 从 SQL 收集本月数据
- .net - Entity Framework Core 并发异常导致恶意查询执行
- python - 查找字符串的回文分解
- java - Can I return an API response without waiting on other external API calls in Spring Boot?
- python - Python 变量理解
- angular - 如何修复错误错误:默认包未在 Nebular 中注册
- rust - 通过 Rust 中的非静态函数数组管道图像
- python-3.x - Pypy Windows 10 中的模块安装问题