我的桌子。
表1
Id ParentId Name Code
1 Null John
2 1 Harry
3 1 Mary
4 2 Emma
5 2 Kyle
6 4 Robert
7 Null Rohit
我想为每个人分配以下格式的唯一层次代码
需要输出
Id ParentId Name Code
1 Null John 1
2 1 Harry 1.1
3 1 Mary 1.2
4 2 Emma 1.1.1
5 2 Kyle 1.1.2
6 4 Robert 1.1.1.1
7 Null Rohit 2
以此类推。
答案 0 :(得分:1)
我希望我正确无误...
您可以将递归CTE与ROW_NUMBER()
一起使用来创建代码。
DECLARE @dummy TABLE(Id INT,ParentId INT,[Name] VARCHAR(100));
INSERT INTO @dummy(Id,ParentId,[Name]) VALUES
(1,Null,'John')
,(2,1 ,'Harry')
,(3,1 ,'Mary')
,(4,2 ,'Emma')
,(5,2 ,'Kyle')
,(6,4 ,'Robert')
,(7,Null,'Rohit');
WITH recCTE AS
(
SELECT Id,ParentId,[Name]
,CONCAT(N'.',CAST(ROW_NUMBER() OVER(ORDER BY Id) AS NVARCHAR(MAX))) AS Code
FROM @dummy WHERE ParentId IS NULL
UNION ALL
SELECT d.Id,d.ParentId,d.[Name]
,CONCAT(r.Code,N'.', ROW_NUMBER() OVER(ORDER BY d.Id))
FROM @dummy d
INNER JOIN recCTE r ON d.ParentId=r.Id
)
SELECT Id,ParentId,[Name]
,STUFF(Code,1,1,'') AS Code
FROM RecCTE;
简而言之:
我们用ParentId IS NULL
挑选行,并给它们一个运行号。
现在,我们遍历它们(实际上是一个隐藏的RBAR ),并再次给他们的孩子一个连续的号码。
我们会一直这样做,直到没有剩下任何东西为止。
最后的SELECT
需要一个STUFF
才能摆脱第一个点。
使用这样的扩展名,您可以创建字母数字可排序代码:
WITH recCTE AS
(
SELECT Id,ParentId,[Name]
,CONCAT(N'.',CAST(ROW_NUMBER() OVER(ORDER BY Id) AS NVARCHAR(MAX))) AS Code
,CONCAT(N'000',CAST(ROW_NUMBER() OVER(ORDER BY Id) AS NVARCHAR(MAX))) AS Code2
FROM @dummy WHERE ParentId IS NULL
UNION ALL
SELECT d.Id,d.ParentId,d.[Name]
,CONCAT(r.Code,N'.', ROW_NUMBER() OVER(ORDER BY d.Id))
,CONCAT(r.Code2,RIGHT(CONCAT('0000',ROW_NUMBER() OVER(ORDER BY d.Id)),4))
FROM @dummy d
INNER JOIN recCTE r ON d.ParentId=r.Id
)
SELECT Id,ParentId,[Name]
,STUFF(Code,1,1,'') AS Code
,Code2
FROM RecCTE
ORDER BY Code2;