Как вы динамически назначаете уникальный код для каждой строки в иерархической таблице? - PullRequest
0 голосов
/ 08 июля 2019

Мой стол.

Table1

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

и т. Д.

1 Ответ

1 голос
/ 08 июля 2019

Надеюсь, я правильно понял ...

Вы можете использовать рекурсивный 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...