복붙노트

[SQL] 부모와 무한 어린이를 반환하는 문을 선택

SQL

부모와 무한 어린이를 반환하는 문을 선택

같은 같은 테이블 구조 보내기

ID      ParentID      Name
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

ID가 = 1을 부여 할 때 나는 테이블의 모든 데이터를 반환 단일 SQL 문 / 함수에 대한 우아한 (가능한 경우) 솔루션을 찾고 있어요

내 결과는 같을 것이다 그래서 :

ID      ParentID      Name
1       NULL          A root
3       1             Child of 1
4       3                Grandchild of 1
5       4                   Great grandchild of 1
6       1             Child of 1

대부분의 경우 그들은 단지 수준의 지정된 번호로 찾고있을 것 같다하지만 나는 SO에 비슷한 질문을 본 적이있다.

이 구조는 궁극적으로 무한 할 수있다 - 다른 많은 아이들과 아이들과 폴더,

이것이 가능한가? 그렇다면, 어떻게 그것을 달성 할 것인가?

해결법

  1. ==============================

    1.그래서이 답변을 참조 :

    그래서이 답변을 참조 :

    SQL 서버 CTE 부모 자식 재귀

    다음은 스키마 작업 버전입니다 :

    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')
    ;
    
    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
    

    키 부분은 UNION ALL 레벨의 수를 제한하지 않는 ParentId에 ID 합류 다시 결과 집합에 조인 CTE 생성이다.

  2. ==============================

    2.당신이 필요한 것은 재귀 쿼리입니다. 이 Microsoft TechNet의 예는 예를 들어, 우리는 직원이 아닌 폴더의 계층 구조에 대한려고하지만 당신이 원하는 것을 정확히 않습니다.

    당신이 필요한 것은 재귀 쿼리입니다. 이 Microsoft TechNet의 예는 예를 들어, 우리는 직원이 아닌 폴더의 계층 구조에 대한려고하지만 당신이 원하는 것을 정확히 않습니다.

    링크 된 페이지에서 :

    -- 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);
    

    그리고

    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
    

    당신의 결과는

    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
    
  3. from https://stackoverflow.com/questions/25550850/select-statement-to-return-parent-and-infinite-children by cc-by-sa and MIT license