Select statement to return parent and infinite children

后端 未结 2 963
执念已碎
执念已碎 2020-12-01 20:39

Give the table structure, as something like:

ID      ParentID      Name
1       NULL          A root
2       NULL          Another root
3       1             Chil         


        
相关标签:
2条回答
  • 2020-12-01 20:53

    So referencing this answer:

    Sql Server CTE Parent Child recursive

    Here's a working version with your schema:

    Table Creation Script

    CREATE TABLE YOUR_TABLE
        ([ID] int, [ParentID] int, [Name] varchar(21))
    ;
    
    INSERT INTO YOUR_TABLE
        ([ID], [ParentID], [Name])
    VALUES
        (1, NULL, 'A root'),
        (2, NULL, 'Another root'),
        (3, 1, 'Child of 1'),
        (4, 3, 'Grandchild of 1'),
        (5, 4, 'Great grandchild of 1'),
        (6, 1, 'Child of 1'),
        (7, NULL, 'Another root'),
        (8, 7, 'Child of 6')
    ;
    

    Recursive CTE

    DECLARE @ID INT = 1
    
    ;WITH ParentChildCTE
    AS (
        SELECT ID, ParentId, Name        
        FROM YOUR_TABLE
        WHERE Id = @ID
    
        UNION ALL
    
        SELECT T1.ID, T1.ParentId, T1.Name        
        FROM YOUR_TABLE T1
        INNER JOIN ParentChildCTE T ON T.ID = T1.ParentID
        WHERE T1.ParentID IS NOT NULL
        )
    SELECT *
    FROM ParentChildCTE
    

    The key part is in the CTE creation where the UNION ALL joins back on to the result set, joining ID to ParentId, which doesn't limit the number of level.

    0 讨论(0)
  • 2020-12-01 21:06

    What you need is a recursive query. This Microsoft Technet example does exactly what you want, though in the example, we're going for a hierarchy of employees, not folders.

    From the linked page:

    -- Create an Employee table.
    CREATE TABLE dbo.MyEmployees
    (
    EmployeeID smallint NOT NULL,
    FirstName nvarchar(30)  NOT NULL,
    LastName  nvarchar(40) NOT NULL,
    Title nvarchar(50) NOT NULL,
    DeptID smallint NOT NULL,
    ManagerID int NULL,
     CONSTRAINT PK_EmployeeID PRIMARY KEY CLUSTERED (EmployeeID ASC) 
    );
    -- Populate the table with values.
    INSERT INTO dbo.MyEmployees VALUES 
     (1, N'Ken', N'Sánchez', N'Chief Executive Officer',16,NULL)
    ,(273, N'Brian', N'Welcker', N'Vice President of Sales',3,1)
    ,(274, N'Stephen', N'Jiang', N'North American Sales Manager',3,273)
    ,(275, N'Michael', N'Blythe', N'Sales Representative',3,274)
    ,(276, N'Linda', N'Mitchell', N'Sales Representative',3,274)
    ,(285, N'Syed', N'Abbas', N'Pacific Sales Manager',3,273)
    ,(286, N'Lynn', N'Tsoflias', N'Sales Representative',3,285)
    ,(16,  N'David',N'Bradley', N'Marketing Manager', 4, 273)
    ,(23,  N'Mary', N'Gibson', N'Marketing Specialist', 4, 16);
    

    and then

    WITH DirectReports (ManagerID, EmployeeID, Title, DeptID, Level)
    AS
    (
    -- Anchor member definition
        SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID, 
            0 AS Level
        FROM dbo.MyEmployees AS e
        INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
            ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
        WHERE ManagerID IS NULL
        UNION ALL
    -- Recursive member definition
        SELECT e.ManagerID, e.EmployeeID, e.Title, edh.DepartmentID,
            Level + 1
        FROM dbo.MyEmployees AS e
        INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
            ON e.EmployeeID = edh.BusinessEntityID AND edh.EndDate IS NULL
        INNER JOIN DirectReports AS d
            ON e.ManagerID = d.EmployeeID
    )
    -- Statement that executes the CTE
    SELECT ManagerID, EmployeeID, Title, DeptID, Level
    FROM DirectReports
    INNER JOIN HumanResources.Department AS dp
        ON DirectReports.DeptID = dp.DepartmentID
    WHERE dp.GroupName = N'Sales and Marketing' OR Level = 0;
    GO
    

    and your result is

    ManagerID EmployeeID Title                         Level
    --------- ---------- ----------------------------- ------
    NULL      1          Chief Executive Officer       0
    1         273        Vice President of Sales       1
    273       16         Marketing Manager             2
    273       274        North American Sales Manager  2
    273       285        Pacific Sales Manager         2
    16        23         Marketing Specialist          3
    274       275        Sales Representative          3
    274       276        Sales Representative          3
    285       286        Sales Representative          3
    
    0 讨论(0)
提交回复
热议问题