1 분 소요

정방향 재귀쿼리 (부모 -> 자식)

WITH ORIGIN_TREE AS (
    -- 초기 검색결과 노드부터 시작
    SELECT
        A.SEQ as "treeId"
        , IIF(A.PARENT_SEQ = 0, NULL, A.PARENT_SEQ) as "treeParentId"
        , A.LEVEL as "treeLevel"
        , A.SORT as "treeOrder"
    FROM A_TABLE AS A
    WHERE
        A.DEL_YN = 'N'
    -- 검색결과 노드부터 하위 노드로 재귀하며 트리 구성 (정방향)
    UNION ALL
    SELECT
        CHILD_NODE.SEQ as "treeId"
        , IIF(CHILD_NODE.PARENT_SEQ = 0, NULL, CHILD_NODE.PARENT_SEQ) as "treeParentId"
        , CHILD_NODE.LEVEL as "treeLevel"
        , CHILD_NODE.SORT as "treeOrder"
    FROM A_TABLE AS CHILD_NODE
    INNER JOIN ORIGIN_TREE
    ON ( ORIGIN_TREE.treeId = CHILD_NODE.PARENT_SEQ )
    WHERE CHILD_NODE.DEL_YN = 'N'
)
--자식들중 같은 부모를 가진경우 중복이 되기때문에 중복 제거
, DISTINCT_TREE as (
    SELECT * FROM (
        SELECT ORIGIN_TREE.*
            , ROW_NUMBER() OVER (PARTITION BY ORIGIN_TREE.treeId ORDER BY ORIGIN_TREE.treeLevel ASC, ORIGIN_TREE.treeOrder ASC, ORIGIN_TREE.treeId ASC) as "rnum"
        FROM ORIGIN_TREE ) AS TEMP
    WHERE TEMP.rnum = 1
)
, RESULT_TREE as (
    SELECT
        CONVERT(NVARCHAR(MAX), DISTINCT_TREE.treeId) as "treeId"
        , DISTINCT_TREE.treeParentId as "treeParentId"
        , DISTINCT_TREE.treeLevel as "treeLevel"
        , DISTINCT_TREE.treeOrder as "treeOrder"

        -- A_TABLE 정보
        , A.SEQ as "seq"
        , A.NAME as "name"
        , A.PHONE as "phone"
        , A.AGE as "age"
    FROM DISTINCT_TREE
    INNER JOIN A_TABLE as A
    ON A.SEQ = DISTINCT_TREE.treeId
)

SELECT * FROM RESULT_TREE
ORDER BY
    RESULT_TREE.treeLevel ASC
    ,RESULT_TREE.treeOrder ASC
;

역방향 재귀쿼리 (자식 -> 부모)

WITH ORIGIN_TREE AS (
    SELECT
        A.SEQ as "treeId"
        , IIF(A.PARENT_SEQ = 0, NULL, A.PARENT_SEQ) as "treeParentId"
        , A.LEVEL as "treeLevel"
        , A.SORT as "treeOrder"
    FROM A_TABLE AS A
    WHERE
        A.DEL_YN = 'N'
    -- 검색결과 노드부터 상위 노드로 재귀하며 트리 구성 (역순)
    UNION ALL
    SELECT
        PARENT_NODE.SEQ as "treeId"
        , IIF(PARENT_NODE.PARENT_SEQ = 0, NULL, PARENT_NODE.PARENT_SEQ) as "treeParentId"
        , PARENT_NODE.LEVEL as "treeLevel"
        , PARENT_NODE.SORT as "treeOrder"
    FROM A_TABLE AS PARENT_NODE
    INNER JOIN ORIGIN_TREE
    ON ( ORIGIN_TREE.treeParentId = PARENT_NODE.SEQ )
    WHERE
        PARENT_NODE.DEL_YN = 'N'
)
--자식들중 같은 부모를 가진경우 중복이 되기때문에 중복 제거
,DISTINCT_TREE as (
    SELECT * FROM (
        SELECT ORIGIN_TREE.*
            , ROW_NUMBER() OVER (PARTITION BY ORIGIN_TREE.treeId ORDER BY ORIGIN_TREE.treeLevel ASC, ORIGIN_TREE.treeOrder ASC, ORIGIN_TREE.treeId ASC) as "rnum"
        FROM ORIGIN_TREE ) AS TEMP
    WHERE TEMP.rnum = 1
)
,RESULT_TREE as (
    SELECT
        CONVERT(NVARCHAR(MAX), DISTINCT_TREE.treeId) as "treeId"
        , DISTINCT_TREE.treeParentId as "treeParentId"
        , DISTINCT_TREE.treeLevel as "treeLevel"
        , DISTINCT_TREE.treeOrder as "treeOrder"

        -- A_TABLE 정보
        , A.SEQ as "seq"
        , A.NAME as "name"
        , A.PHONE as "phone"
        , A.AGE as "age"
    FROM DISTINCT_TREE
    INNER JOIN A_TABLE as A
    ON A.SEQ = DISTINCT_TREE.treeId
)

SELECT * FROM RESULT_TREE
ORDER BY
    RESULT_TREE.treeLevel ASC
    ,RESULT_TREE.treeOrder ASC
;

카테고리:

업데이트:

댓글남기기