每个节点ID的层次结构

时间:2019-07-10 09:40:04

标签: sql-server tsql sql-server-2014

我有一个递归数据库表和所有表数据的分层视图

CREATE VIEW dbo.vw_hierarchicalView
AS
    WITH hView (Id,
                    IdParent,
                    Level)
    AS
    (
        SELECT tableParent.Id,
               tableParent.IdParent,
               1 AS Level
        FROM dbo.vw_ComplaintWithStatus tableParent
        WHERE tableParent.IdParent IS NULL
        UNION ALL SELECT tableChild.Id,
                         tableChild.IdParent,
                         hw.level + 1 AS  Level
                 FROM dbo.vw_ComplaintWithStatus tableChild
                      INNER JOIN hView hw ON  tableChild.IdParent = hw.Id
    )
    SELECT final.Id,
           final.IdParent,
           ISNULL(final.Level, 1) AS Level
    FROM hView final

此视图的结果是此表为: Result of view

我需要每个根级别都有其自己的唯一ID,并将此ID复制到子级。 所需的结果是这样的:

Desired result

这可能吗? 谢谢您的建议和帮助。

http://sqlfiddle.com/#!18/8400c/3

    CREATE TABLE Entries
(
  ID BIGINT NOT NULL PRIMARY KEY,
  ENTRY NVARCHAR(MAX) NOT NULL,
  PARENT_ID BIGINT NULL FOREIGN KEY REFERENCES Entries (ID)
)

INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (1, 'TEXT', NULL)
INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (2, 'TEXT', 1)
INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (3, 'TEXT', 2)
INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (4, 'TEXT', NULL)
INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (5, 'TEXT', 4)
INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (6, 'TEXT', 4)
INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (7, 'TEXT', 6)
INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (8, 'TEXT', NULL)
INSERT INTO ENTRIES(ID, ENTRY, PARENT_ID) VALUES (9, 'TEXT', 1)

2 个答案:

答案 0 :(得分:2)

如果在根节点的递归CTE中添加额外的列,则可以获取节点号的DENSE_RANK

WITH rCTE AS(
    SELECT E.ID AS Id,
           E.PARENT_ID AS IdParent,
           1 AS [Level],
           E.ID AS RootID
    FROM dbo.Entries E
    WHERE E.PARENT_ID IS NULL
    UNION ALL
    SELECT E.ID AS Id,
           E.PARENT_ID AS IdParent,
           r.[Level] + 1 AS [Level],
           r.RootID
    FROM rCTE r
         JOIN dbo.Entries E ON r.ID = E.PARENT_ID)
SELECT r.Id,
       r.IdParent,
       r.Level,
       DENSE_RANK() OVER (ORDER BY r.RootID) AS [Node]
FROM rCTe r;

答案 1 :(得分:2)

您可以在锚定部分中包含Row number(),而在递归部分中具有相同的子级值

WITH hView (Id,
                IdParent,
                Level,node)
    AS
    (
        SELECT tableParent.Id,
               tableParent.Parent_Id,
               1 AS Level,
            row_number()over (order by id)   AS  node
        FROM Entries tableParent
        WHERE tableParent.Parent_Id IS NULL
        UNION ALL 
        SELECT tableChild.Id,
               tableChild.Parent_Id,
               hw.level + 1 AS  Level,
                hw.node  AS  node
        FROM dbo.Entries tableChild
             INNER JOIN hView hw ON  tableChild.Parent_Id = hw.Id
    )
    SELECT final.Id,
           final.IdParent,
           ISNULL(final.Level, 1) AS Level
           , node
    FROM hView final
    order by node