如何为 sql 服务器中的分层数据生成序列号

How to generate sequence numbers for hierarchical data in sql server

我在 sql 中创建了一个函数来获取 hierarchy.I 中的序列号 table 调用了 Goals.the table 的结构如下

 GoalId      ParentId   Goalstatement
----------   ----------  ----------
1               0          abc
2               0          def
3               1          acc
4               2          efc
5               3          dec
6               0          efc
7               3          jhg

我想写一个函数来得到结果

Serial no       GoalId           ParentId        GoalStatement
----------       ----------       ----------     --------------------
1                1                 0              
2                2                 0
3                6                 0
1.1              3                 1
1.1.1            5                 3
1.1.2            7                 3
2.1              4                 2

----------

我试过使用常见的 table 表达式

WITH Hierarchy(GoalID, ParentId, Parents)
AS
(
    SELECT GoalID,  GoalParentID, CAST('' AS VARCHAR(MAX))
        FROM Goals AS FirtGeneration
        WHERE GoalParentID =0    
    UNION ALL
    SELECT NextGeneration.GoalID, NextGeneration.GoalParentID, 
    CAST(CASE WHEN Parent.Parents = ''
        THEN(CAST(NextGeneration.GoalParentID AS VARCHAR(MAX)))
        ELSE(Parent.Parents + '.' + CAST(NextGeneration.GoalParentID AS VARCHAR(MAX)))
    END AS VARCHAR(MAX))
        FROM Goals AS NextGeneration
        INNER JOIN Hierarchy AS Parent ON NextGeneration.GoalParentID = Parent.GoalID    
)
SELECT * 
    FROM Hierarchy 
OPTION(MAXRECURSION 32767)

谁能帮我写一个函数来分层创建序列号

您的递归 CTE 非常接近,但您需要添加 ROW_NUMBER() 以便在层次结构的每个级别生成序号。试试这个;

DECLARE @Goals TABLE (GoalId INT, GoalParentID INT, Goalstatement VARCHAR(100))

INSERT @Goals VALUES 
(1, 0, 'abc'),
(2, 0, 'def'),
(3, 1, 'acc'),
(4, 2, 'efc'),
(5, 3, 'dec'),
(6, 0, 'efc'),
(7, 3, 'jhg')

;WITH NumberedGoals(GoalId, GoalParentID, Goalstatement, GoalSequence) AS (
    SELECT
        GoalId, GoalParentID, Goalstatement, ROW_NUMBER() OVER (PARTITION BY GoalParentID ORDER BY GoalId) AS GoalSequence
    FROM
        @Goals
), Hierarchy(GoalID, GoalParentID, GoalSequence, Parents)
AS
(
    SELECT GoalID, GoalParentID, GoalSequence, CAST(GoalSequence AS VARCHAR(MAX))
        FROM NumberedGoals AS FirtGeneration
        WHERE GoalParentID = 0    
    UNION ALL
    SELECT NextGeneration.GoalID, NextGeneration.GoalParentID, NextGeneration.GoalSequence,
        CAST(CASE WHEN Parent.Parents = ''
            THEN(CAST(NextGeneration.GoalSequence AS VARCHAR(MAX)))
            ELSE(Parent.Parents + '.' + CAST(NextGeneration.GoalSequence AS VARCHAR(MAX)))
        END AS VARCHAR(MAX))
        FROM NumberedGoals AS NextGeneration
        INNER JOIN Hierarchy AS Parent ON NextGeneration.GoalParentID = Parent.GoalID    
)
SELECT h.Parents as [Serial no], h.GoalId, h.GoalParentId, g.GoalStatement
    FROM Hierarchy h
    JOIN @Goals g ON g.GoalID = h.GoalID
OPTION (MAXRECURSION 32767)
;with Hierarchy
as
(
    select GoalID, 
           ParentId,
           Row_Number() over(partition by ParentId order by GoalID) as number, 
           cast(Row_Number() over(partition by ParentId order by GoalID) as nvarchar(200)) newnumber
    from Goals where ParentId = 0
    Union All
      Select p.GoalId,
             p.ParentId,
            Row_Number() over(partition by p.ParentId order by p.GoalID) as number,
            cast(cte.newnumber + '.' + cast(Row_Number() over(partition by p.ParentId order by p.GoalID) as nvarchar(200)) as nvarchar(200)) newnumber
      From Goals p
      Join Hierarchy cte On cte.GoalId = p.ParentId
)

select * from Hierarchy