sql - 如何编写SQL语句返回每个根的所有孩子,扩展到每个根
问题描述
我有一张桌子。[contents] 的值可以插入任何单词(以下仅为示例)
create table #TreeTable (
Id uniqueidentifier,
Contents NVARCHAR(200),
ParentId uniqueidentifier,
Floors Int,
Sort Int,
)
insert into #TreeTable([Id], [ParentId], [Contents],[Floors],[Sort]) values
(1, 0, '1',1,1),
(2, 0, '2',1,2),
(3, 1, '1-1',2,1),
(4, 1, '1-2',2,2),
(5, 2, '2-1',2,1),
(6, 3, '1-1-1',3,1),
(7, 4, '1-2-1',3,1);
(8, 4, '1-2-2',3,2),
(9, 6, '1-1-1-1',4,1),
(10, 6,'1-1-1-2',4,2);
我想编写一个 T-SQL 语句,该语句将返回具有根 ID 的每个根的所有子节点,下面是我期望的结果
[Id][ParentId][Contents] [Levels][Sort]
(1, 0, '1', 1, 1)
(3, 1, '1-1', 2, 1)
(6, 3, '1-1-1', 3, 1)
(9, 6, '1-1-1-1', 4, 1)
(10, 6, '1-1-1-2', 4, 2)
(4, 1, '1-2', 2, 2)
(7, 4, '1-2-1', 3, 1)
(8, 4, '1-2-2', 3, 2)
(2, 0, '2', 1, 2)
(5, 2, '2-1', 2, 1)
树的深度可以任意长
我尝试使用这个,但结果不是我所期望的
with RecursiveTable as(
------ start-------
SELECT a.*
FROM TreeTable a
WHERE
a.ParentId = 0
------ end ---------
union all
SELECT b.*
FROM TreeTable b
join RecursiveTable a on a.Id =b.ParentId
)
select * from RecursiveTable
解决方案
如果我们可以相信[Contents]
价值观,那么只需
SELECT [Id],
[ParentId],
[Contents],
LEN([Contents]) - LEN(REPLACE([Contents], '-', '')) + 1 [Levels],
[Sort]
FROM #TreeTable
ORDER BY [Contents];
如果没有那么
WITH cte AS
(
SELECT [Id], [ParentId], CAST([Sort] AS NCHAR), [Sort], 1 [Levels]
FROM #TreeTable
WHERE [ParentId] = 0
UNION ALL
SELECT t.[Id], t.[ParentId], cte.[Contents] + '-' + t.[Sort], t.[Sort], 1 + cte.[Levels]
FROM #TreeTable t
JOIN cte ON t.[ParentId] = cte.[Id]
)
SELECT [Id], [ParentId], [Contents], [Levels], [Sort]
FROM cte
ORDER BY [Contents];
小提琴(自己优化类型以适应它们在 CTE 中的匹配)。
推荐阅读
- google-chrome - Chrome 84+:一个网站想要打开这个应用程序:处理程序
- hyperledger-fabric - 配置超级账本结构时出现问题
- ios - 应用程序终止时iOS Swift处理通知单击
- python - 如何在用户的帖子上设置关注/取消关注按钮
- typescript - 在 Vuetify 和 Vue.js 中选择自动完成数字和更改数据表数据
- html - 确保 Flex 容器内部 Div 在窗口调整大小时保持其尺寸 - CSS
- spring-boot - 为什么我可以从端点框架中排除 servlet-api,但不能从端点管理控制应用程序引擎全部中排除?
- java - 努力将文本拆分为数组的逻辑
- c++ - 用参数推断 lambda 的返回类型
- python - 已解决:如何删除密钥重复错误 Django?