계층형 구조에서 자식노드가 있는 LEVEL만 보여줄수가 있을까요 1 2 2,136

by DB입문자 [Oracle 기초] 계층형 START WITH 계층형 자식 [2021.11.08 13:38:09]


캡처.JPG (51,123Bytes)

 SELECT A.EOPMU_GB,
                  A.EOPMU_CD,
                  A.HIGH_CD,
                  A.MENU_CD,
                  LPAD('   ', 8*(LEVEL-1))||MENU_NM MENU_NM, 
                  A.MENU_LEVEL,
                  A.SAYONG_YN,
                  LEVEL AS LV
             FROM CS_MENU_M A 
            WHERE     1 = 1
                  AND A.EOPMU_GB = 'BURE'
                  AND A.EOPMU_CD = '601'
                  AND NOT EXISTS
                             (SELECT ROLE_CD, MENU_CD
                                FROM CS_ROLEMENU_M B
                               WHERE     A.MENU_CD = B.MENU_CD
                                     AND A.EOPMU_GB = B.EOPMU_GB
                                     AND B.ROLE_CD = 'AM1000')
                  AND MENU_LEVEL <= 2       
       START WITH MENU_LEVEL = 1
       CONNECT BY PRIOR MENU_CD = HIGH_CD
    ORDER SIBLINGS BY SORT, MENU_CD  

 

이렇게 쿼리를 작성하면 결과가 아래와 같이 나오는데

LEVEL이 1인경우 밑에 하위 자식들이 있을경우만 메뉴명을 보여주고 싶습니다.

예를들면 현재 "기초정보관리" 메뉴는 밑에 하위 노드들이 없기 때문에 안보여지고 "과정관리(일반)" 은 밑에 하위노드들이 있기때문에 보여지게 하고싶습니다

방법이 있을까요?? 감사합니다

※ 하위노드가 없을경우 LEVEL 1 인 MENU_NM 자체를 안보이게 하고싶습니다

 

by 마농 [2021.11.08 13:55:43]

1. 요청하신 사항은 간단하게 조건 추가 하여 해결이 가능한데...
- (1레벨) 중 (최하위) 조건이 (아닌) 걸 찾으면 됩니다.
- AND NOT (LEVEL = 1 AND CONNECT_BT_ISLEAF = 1)
- NOT 을 괄호 안으로 넣어 보면
- AND (LEVEL != 1 OR CONNECT_BT_ISLEAF != 1)
2. 기존 쿼리에 비효율이 없는지 확인이 필요합니다.
- WHERE 절 조건은 계층 쿼리를 모든 자료에 대해 수행한 후 비로서 자료를 걸러내는 거구요
- 계층 쿼리를 수행하면서 미리 필요한 것만 걸러낸다면 성능 개선 효과가 엄청날 것입니다.
- 기존 WHERE 절에서 조건을 주는 부분들이
- CONNECT BY 절 이나 START WITH 절 조건으로 처리하는게 맞지 않느가 검토가 필요합니다.

-- 쿼리 개선 예시 --
SELECT a.eopmu_gb
     , a.eopmu_cd
     , a.high_cd
     , a.menu_cd
     , LPAD('   ', (LEVEL-1)*8) || menu_nm menu_nm
     , a.menu_level
     , a.sayong_yn
     , LEVEL AS lv
  FROM cs_menu_m a
 WHERE 1 = 1
   AND NOT (LEVEL = 1 AND CONNECT_BT_ISLEAF = 1)
 START WITH menu_level = 1
        AND eopmu_gb   = 'BURE'
        AND eopmu_cd   = '601'
        AND NOT EXISTS (SELECT role_cd, menu_cd
                          FROM cs_rolemenu_m b
                         WHERE b.menu_cd  = a.menu_cd 
                           AND b.eopmu_gb = a.eopmu_gb
                           AND b.role_cd  = 'AM1000'
                        )
 CONNECT BY PRIOR menu_cd  = high_cd
        AND PRIOR eopmu_gb = eopmu_gb
        AND PRIOR eopmu_cd = eopmu_cd
        AND menu_level    <= 2
        AND NOT EXISTS (SELECT role_cd, menu_cd
                          FROM cs_rolemenu_m b
                         WHERE b.menu_cd  = a.menu_cd 
                           AND b.eopmu_gb = a.eopmu_gb
                           AND b.role_cd  = 'AM1000'
                        )
 ORDER SIBLINGS BY sort, menu_cd
;

 


by DB입문자 [2021.11.08 14:19:01]

START WITH 안에서 조건절 처리를 할수있는지 몰랐었는데 이걸보니까 바로 이해가 되네요

정말 감사드립니다ㅎㅎ 더열심히 공부해야겠습니다

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입