Oracle SQL에서 Connect와 Claus를 시작하십시오
-
12-12-2019 - |
문제
이하의 테스트 데이터에 대한 계층 적 데이터를 원합니다.사용자 '존스'의 경우 아래 레코드를 가져와야합니다.나는 연결에 문제가 있고 조항으로 시작합니다. MENU_ITEMS와 ROLE_MENU_ITEMS 테이블간에 몇 가지 가입 문제가 있음을 생각합니다.
사용자 및 해당 역할이 데이터 아래에서 FectH를 필요로하는 경우
select mi.id, mi.NAME,mi.MEN_ID,mi.ICON,mi.ACTION--,r.NAME
from
menu_items mi,
role_menu_items rmi,
roles r,
USERS U,
USER_ROLES UR
where
mi.ID=rmi.MIT_ID and
rmi.ROL_ID=r.id and
r.id=UR.ROLE_ID and
U.ID=UR.USER_ID and
U.NAME='jones'
start with mi.men_id is null
connect by prior mi.ID=mi.men_id
.
출력
1 Menu1 Menu1 /images/home.gif
3 Help Help
4 page1 a 1 page1 1 /images/email.gif
7 about d 1 about 3
.
Insert into MENU_ITEMS (ID,NAME,SHORTCUT,DISPLAY_SEQUENCE,ACTION,MEN_ID,ICON)
values (1,'Menu1',null,null,'Menu1',null,'/images/home.gif');
Insert into MENU_ITEMS (ID,NAME,SHORTCUT,DISPLAY_SEQUENCE,ACTION,MEN_ID,ICON)
values (2,'Menu2',null,null,'Menu2',null,null);
Insert into MENU_ITEMS (ID,NAME,SHORTCUT,DISPLAY_SEQUENCE,ACTION,MEN_ID,ICON)
values (3,'Help',null,null,'Help',null,null);
Insert into MENU_ITEMS (ID,NAME,SHORTCUT,DISPLAY_SEQUENCE,ACTION,MEN_ID,ICON)
values (4,'page1','a',1,'page1',1,'/images/email.gif');
Insert into MENU_ITEMS (ID,NAME,SHORTCUT,DISPLAY_SEQUENCE,ACTION,MEN_ID,ICON)
values (5,'page2','b',2,'page2',1,null);
Insert into MENU_ITEMS (ID,NAME,SHORTCUT,DISPLAY_SEQUENCE,ACTION,MEN_ID,ICON)
values (6,'page3','c',1,'page3',2,'/images/photo.gif');
Insert into MENU_ITEMS (ID,NAME,SHORTCUT,DISPLAY_SEQUENCE,ACTION,MEN_ID,ICON)
values (7,'about','d',1,'about',3,null);
insert into ROLES (ID, NAME)
values (1, 'administrator');
insert into ROLES (ID, NAME)
values (2, 'user');
Insert into ROLE_MENU_ITEMS (ROL_ID,MIT_ID) values (1,4);
Insert into ROLE_MENU_ITEMS (ROL_ID,MIT_ID) values (1,5);
Insert into ROLE_MENU_ITEMS (ROL_ID,MIT_ID) values (1,6);
Insert into ROLE_MENU_ITEMS (ROL_ID,MIT_ID) values (1,7);
Insert into ROLE_MENU_ITEMS (ROL_ID,MIT_ID) values (2,4);
Insert into ROLE_MENU_ITEMS (ROL_ID,MIT_ID) values (2,7);
Insert into USER_ROLES (USER_ID,ROLE_ID) values (2,2);
Insert into USER_ROLES (USER_ID,ROLE_ID) values (1,1);
Insert into USER_ROLES (USER_ID,ROLE_ID) values (3,2);
Insert into USERS (ID,NAME,PASSWORD) values (2,'scott','scott');
Insert into USERS (ID,NAME,PASSWORD) values (1,'john','john');
Insert into USERS (ID,NAME,PASSWORD) values (3,'jones','jones');
. 해결책
나쁜 방식이지만 가능하지만
1. 사용자 역할에 대한 모든 menu_id 선택
select RMI.MIT_ID
from ROLE_MENU_ITEMS RMI
, ROLES R
, USERS U
, USER_ROLES UR
where RMI.ROL_ID = R.ID
and R.ID = UR.ROLE_ID
and U.ID = UR.USER_ID
and U.NAME = 'jones'
.
2. 역방향 hierary 쿼리
select MI.*
, max(LEVEL) over () + 1 - level as rev_level
, lpad(' ', (max(LEVEL) over () + 1 - LEVEL) * 3, ' ') || MI.NAME as LEVEL_NAME
, rownum RN
from MENU_ITEMS MI
connect by prior MEN_ID = ID
start with ID IN (select RMI.MIT_ID
from ROLE_MENU_ITEMS RMI
, ROLES R
, USERS U
, USER_ROLES UR
where RMI.ROL_ID = R.ID
and R.ID = UR.ROLE_ID
and U.ID = UR.USER_ID
and U.NAME = 'jones')
.
3. 역방향 (역 상승 쿼리)
select ID
, NAME
, SHORTCUT
, DISPLAY_SEQUENCE
, ACTION
, MEN_ID
, ICON
, LEVEL_NAME
from
(
select MI.*
, max(LEVEL) over () + 1 - level as rev_level
, lpad(' ', (max(LEVEL) over () + 1 - LEVEL) * 3, ' ') || MI.NAME as LEVEL_NAME
, rownum RN
from MENU_ITEMS MI
connect by prior MEN_ID = ID
start with ID IN (select RMI.MIT_ID
from ROLE_MENU_ITEMS RMI
, ROLES R
, USERS U
, USER_ROLES UR
where RMI.ROL_ID = R.ID
and R.ID = UR.ROLE_ID
and U.ID = UR.USER_ID
and U.NAME = 'jones')
)
group by ID --distinct with order
, name
, SHORTCUT
, DISPLAY_SEQUENCE
, ACTION
, MEN_ID
, ICON
, LEVEL_NAME
order by min(-RN)
.
하위 쿼리를 사용하여 루트 항목을 ID로 유지할 수 있습니다
select ID
, NAME
, SHORTCUT
, DISPLAY_SEQUENCE
, ACTION
, MEN_ID
, ICON
, LEVEL_NAME
from
(
select ID
, NAME
, SHORTCUT
, DISPLAY_SEQUENCE
, ACTION
, MEN_ID
, ICON
, MAX(LVL) OVER () + 1 - LVL
, rpad(' ', (max(LVL) over () + 1 - LVL) * 3, ' ') || NAME as LEVEL_NAME
, RN
from (
select MI.*
, rownum RN
, level LVL
from MENU_ITEMS MI
connect by prior MEN_ID = ID
start with ID IN (select RMI.MIT_ID
from ROLE_MENU_ITEMS RMI
, ROLES R
, USERS U
, USER_ROLES UR
where RMI.ROL_ID = R.ID
and R.ID = UR.ROLE_ID
and U.ID = UR.USER_ID
and U.NAME = 'jones')
order siblings by -ID
)
)
group by ID --distinct with order
, name
, SHORTCUT
, DISPLAY_SEQUENCE
, ACTION
, MEN_ID
, ICON
, LEVEL_NAME
order by min(-RN)
. 제휴하지 않습니다 StackOverflow