by DB입문자 [Oracle 기초] 계층형 START WITH 계층형 자식 [2021.11.08 13:38:09]
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 자체를 안보이게 하고싶습니다
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 ;