Select statement to return parent and infinite children

后端 未结 2 965
执念已碎
执念已碎 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 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
    

提交回复
热议问题