계층형구조 (CONNECT BY)

2012. 11. 5. 10:34

===================================================================

[예]


SELECT

        LEVEL AS LEV

      , MENU.*

FROM

        TBL_MENU  MENU

WHERE               MENU_TYPE_CD = '1'

START WITH          MENU.MENU_ID = 'TOP'

CONNECT BY PRIOR    MENU.MENU_ID = MENU.UP_MENU_ID

ORDER SIBLINGS BY   MENU_SEQ


===================================================================

[풀이]


UP_MENU_ID 가 'TOP'인 것부터 순환고리를 시작하며 

동일 레벨일경우(즉, UP_MENU_ID 가 'TOP'으로 하는 여러 ROW)는 MENU_SEQ가 먼저인것 부터 계층구조

그리고 마지막으로 MENU_TYPE_CD가 '1'인것만 최종 추출


===================================================================



◈ LEVEL 예약어 : depth


◈ CONNECT BY의 실행순서

    (1) START WITH 절

    (2) CONNECT BY 절

    (3) WHERE 절


◈ 

    START WITH : 시작위치 설정 (서브쿼리를 사용가능)

    CONNECT BY : 순환고리의 조건 (서브쿼리를 사용불가)

    ORDER SIBLINGS BY : 같은 레벨중 순환고리 순서를 정할때 사용


◈ PRIOR 의 위치 

    (1) CONNECT BY PRIOR 자식컬럼 =       부모컬럼  ==> 부모에서 자식으로 트리 구성

    (2) CONNECT BY       자식컬럼 = PRIOR 부모컬럼  ==> 자식에서 부모으로 트리 구성


◈ 데이터가 많아질 경우....


    - START WITH MENU_ID = 'TOP' 

          MENU_ID 컬럼에 index가 생성되어 있지 않는다면 속도를 보장할 수 없습니다.


    - CONNECT BY PRIOR MENU_ID = UP_MENU_ID 

          역시 PRIOR 쪽의 컬럼값이 상수가 되기 때문에 UP_MENU_ID컬럼에 index를 생성하여야 CONNECT BY의 속도를 보장할 수 있습니다.


    - 계층구조를 CONNECT BY, START WITH로 풀면 부분범위 처리가 불가능하고 Desc으로 표현하기가 어렵 습니다.


◈  

    (1) '상품' 메뉴는 모두 출력 안함.

    SELECT

            LEVEL AS LEV

          , MENU.*

    FROM    

            TBL_MENU  MENU

    WHERE               MENU.MENU_NAME  <> '상품'

    START WITH          MENU.MENU_ID = 'TOP'

    CONNECT BY PRIOR    MENU.MENU_ID = MENU.UP_MENU_ID

    ORDER SIBLINGS BY   MENU_SEQ 

    

    (2) '상품'메뉴 밑으로 모든 메뉴는 출력안함.

    SELECT

            LEVEL AS LEV

          , MENU.*

    FROM    

            TBL_MENU  MENU

    START WITH          MENU.MENU_ID    = 'TOP'

    CONNECT BY PRIOR    MENU.MENU_ID    = MENU.UP_MENU_ID

    AND                 MENU.MENU_NAME  <> '상품'

    ORDER SIBLINGS BY   MENU_SEQ 

    

    ** 참고) 메뉴중 2LEVEL까지만 결과 출력

    (WHERE조건으로도 LEVEL <= 2가능함. 그러나 권하지는 않는다. 

     왜? WHERE 조건은 모든 나온결과에 대해서 FILTER하지만 CONNECT BY절의 조건으로 넣으면 순환자체를 안한다. 즉 성능에 좋다)

    SELECT

            LEVEL AS LEV

          , MENU.*

    FROM    

            TBL_MENU  MENU

    START WITH          MENU.MENU_ID    = 'TOP'

    CONNECT BY PRIOR    MENU.MENU_ID    = MENU.UP_MENU_ID

    AND                 LEVEL  <= 2

    ORDER SIBLINGS BY   MENU_SEQ     

   

    

◈ 

    (1) 들여쓰기로 결과출력

    SELECT

            LPAD(’ ’, 4*(LEVEL-1)) || MENU.MENU_NAME

          , MENU.*

    FROM

            TBL_MENU  MENU

    WHERE               MENU_TYPE_CD = '1'

    START WITH          MENU.MENU_ID = 'TOP'

    CONNECT BY PRIOR    MENU.MENU_ID = MENU.UP_MENU_ID

    ORDER SIBLINGS BY   MENU_SEQ

    

    (2) 엑셀과 같이 셀 단위로 들여쓰기

    SELECT 

             DECODE(LEV, '1', MENU_NAME, '') AS LEV1

           , DECODE(LEV, '2', MENU_NAME, '') AS LEV2

           , DECODE(LEV, '3', MENU_NAME, '') AS LEV3

           , DECODE(LEV, '4', MENU_NAME, '') AS LEV4

           , DECODE(LEV, '5', MENU_NAME, '') AS LEV5

    FROM

           (

             SELECT

                     LEVEL AS LEV

                   , MENU.*

             FROM    TBL_MENU  MENU

             WHERE               MENU_TYPE_CD = '1'

             START WITH          MENU.MENU_ID = 'TOP'

             CONNECT BY PRIOR    MENU.MENU_ID = MENU.UP_MENU_ID         

             ORDER SIBLINGS BY   MENU_SEQ 

           )



'오라클' 카테고리의 다른 글

패스워드 암호화 .  (0) 2012.12.07
숫자 함수.  (0) 2012.11.15
토드 에서 벌레의 의미..;  (0) 2012.11.02
TOAD 단축키  (0) 2012.10.31
오라클 과거 데이터를 보는 방법. [SYSTIMESTAMP]  (0) 2012.10.30
Posted by 사라링
BLOG main image
.. by 사라링

카테고리

사라링님의 노트 (301)
JSP (31)
J-Query (41)
JAVA (24)
디자인패턴 (1)
스트러츠 (3)
안드로이드 (11)
오라클 (45)
우분투-오라클 (1)
이클립스메뉴얼 (6)
스프링3.0 (23)
자바스크립트 (10)
HTML5.0 (17)
정보처리기사 (1)
기타(컴퓨터 관련) (1)
문제점 해결 (3)
프로젝트 (2)
AJAX (4)
하이버네이트 (3)
트러스트폼 (11)
Jeus (2)
재무관리(회계) (5)
정규식 (5)
아이바티스 (8)
취미 (2)
소프트웨어 보안 관련모음 (0)
정보보안기사 (6)
C언어 베이직 및 프로그램 (3)
보안 관련 용어 정리 (2)
넥사크로 (6)
웹스퀘어_ (0)
Total :
Today : Yesterday :