【问题标题】:How to generate sequence numbers for hierarchical data in sql server如何在sql server中为分层数据生成序列号
【发布时间】:2015-04-13 04:26:24
【问题描述】:

我在sql中创建了一个函数来获取层次结构中的序列号。我有一个名为Goals的表。表的结构如下

 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

----------

我试过公用表表达式

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)

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

【问题讨论】:

    标签: sql-server hierarchy hierarchical-data


    【解决方案1】:

    您的递归 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)
    

    【讨论】:

    • 感谢您的解决方案。但是一个问题为什么(MAXRECURSION 32767) 这似乎很具体?随机?
    • @MisterT 32767 是支持的最大值,请参阅docs
    【解决方案2】:
    ;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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 2011-10-29
      • 1970-01-01
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多