복붙노트

[SQL] 어떻게 특정 노드에 그 리드를 SQL에서 계층 구조의 경로를 생성 할 수 있습니까?

SQL

어떻게 특정 노드에 그 리드를 SQL에서 계층 구조의 경로를 생성 할 수 있습니까?

내 MS SQL 2008 R2 데이터베이스에서 나는이 표를 가지고 :

TABLE [Hierarchy]
[ParentCategoryId] [uniqueidentifier] NULL,
[ChildCategoryId] [uniqueidentifier] NOT NULL

나는 주어진 노드로 이어질 모든 경로를 생성하는 쿼리를 작성해야합니다.

나는 다음과 같은 트리가 그것을 말할 수 있습니다 :

A
-B
--C
-D
--C

로 저장 될 것이다 :

NULL | A
A    | B
A    | D
B    | C
D    | C

C에 대한 경로를 요청하면, 내가 다시 두 개의 경로를 (더 많거나 적은이 같은 기록) 좀하고 싶습니다 :

A > B > C,
A > D > C

해결법

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

    1.여기 내 솔루션은 SQL 바이올린입니다

    여기 내 솔루션은 SQL 바이올린입니다

    DECLARE @child VARCHAR(10) = 'C'
    
        ;WITH children AS
        (
    
           SELECT 
             ParentCategoryId,
            CAST(ISNULL(ParentCategoryId + '->' ,'')  + ChildCategoryId AS VARCHAR(4000)) AS Path
           FROM Hierarchy
           WHERE ChildCategoryId =  @child
         UNION ALL
           SELECT 
             t.ParentCategoryId,
             list= CAST(ISNULL(t.ParentCategoryId  + '->' ,'')  + d.Path AS VARCHAR(4000))
           FROM Hierarchy t
           INNER JOIN children  AS d
                ON t.ChildCategoryId = d.ParentCategoryId
         )
    
        SELECT Path 
        from children c
        WHERE ParentCategoryId IS NULL
    

    산출:

    A->D->C 
    A->B->C 
    

    최신 정보:

    @AlexeiMalashkevich, 단지 경우 얻을, 당신이 시도 할 수 있습니다

    SQL 바이올린

    DECLARE @child VARCHAR(10) = 'C'
    
    ;WITH children AS
    (
    
       SELECT 
         ParentCategoryId,
         ChildCategoryId  AS Path
       FROM Hierarchy
       WHERE ChildCategoryId =  @child
     UNION ALL
       SELECT 
         t.ParentCategoryId,
         d.ParentCategoryId 
       FROM Hierarchy t
       INNER JOIN children  AS d
            ON t.ChildCategoryId = d.ParentCategoryId
     )
    
    SELECT DISTINCT PATH
    from children c
    
  2. ==============================

    2.가능한 해결 방법은 @a_horse_with_no_name에서 언급 한 바와 같이 재귀 CTE를 사용하는 것입니다 :

    가능한 해결 방법은 @a_horse_with_no_name에서 언급 한 바와 같이 재귀 CTE를 사용하는 것입니다 :

    CREATE TABLE [Hierarchy](
    [ParentCategoryId] CHAR(1) NULL,
    [ChildCategoryId] CHAR(1) NOT NULL
    );
    
    
    INSERT INTO Hierarchy
    SELECT NULL, 'A' UNION ALL
    SELECT 'A', 'B' UNION ALL
    SELECT 'A', 'D' UNION ALL
    SELECT 'B', 'C' UNION ALL
    SELECT 'D', 'C';
    
    
    WITH CTE AS (
        SELECT 
            ParentCategoryId, ChildCategoryId, 
            CAST(ISNULL(ParentCategoryId,'') + ChildCategoryId AS VARCHAR(255)) [Path] 
        FROM Hierarchy
        WHERE ParentCategoryId IS NULL
    
        UNION ALL
    
        SELECT 
            H.ParentCategoryId, H.ChildCategoryId, 
            CAST(C.[Path] + ' > ' + H.ChildCategoryId AS VARCHAR(255)) [Path] 
        FROM Hierarchy H
        INNER JOIN CTE C ON C.ChildCategoryId = H.ParentCategoryId
    ) SELECT * FROM CTE;
    
  3. ==============================

    3.즉 흥미로운 계층 구조입니다. 부모가 가능한 자녀의 자녀가 될 수 있도록 보인다. 이 휴식 것이이 코드 논리를 발생하지만,하는 것처럼 그렇게 오래가 발생하지 않는 한이 작동합니다.

    즉 흥미로운 계층 구조입니다. 부모가 가능한 자녀의 자녀가 될 수 있도록 보인다. 이 휴식 것이이 코드 논리를 발생하지만,하는 것처럼 그렇게 오래가 발생하지 않는 한이 작동합니다.

    Create  Function dbo.IdentifyHierarchyPaths (@DeepestChildNode UniqueIdentifier)
    Returns @hierarchy Table
    (
            Hierarchy Varchar(Max)
    )
    As
    Begin
            ;With   BuildHier As
            (
                    Select  Convert(Varchar(Max),h2.ChildCategoryId) As child, Convert(Varchar(Max),h1.ChildCategoryId) + ' > ' +  Convert(Varchar(Max),h2.ChildCategoryId) As hier
                    From    Hierarchy h1
                    Left    Join Hierarchy h2
                            On  h1.ChildCategoryId = h2.ParentCategoryId
                    Where   h1.ParentCategoryId Is Null
                    Union   All
                    Select  Convert(Varchar(Max),h1.ChildCategoryId) As child, bh.hier + ' > ' +  Convert(Varchar(Max),h1.ChildCategoryId) As hier
                    From    BuildHier bh
                    Join    Hierarchy h1
                            On  bh.child = h1.ParentCategoryId
            ),      HierWithTopLevel As
            (
                    Select  Convert(Varchar(Max),ChildCategoryId) As hierarchy
                    From    Hierarchy
                    Where   ParentCategoryId Is Null
                    Union   
                    Select  hier
                    From    BuildHier
            )
            Insert  @hierarchy
            Select  hierarchy
            From    HierWithTopLevel
            Where   Right(hierarchy,36) = Convert(Varchar(36),@DeepestChildNode);
            Return;
    End;
    
  4. from https://stackoverflow.com/questions/14241936/how-can-i-generate-a-hierarchy-path-in-sql-that-leads-to-a-given-node by cc-by-sa and MIT license