1

我想要下面给出的测试数据的分层数据。对于用户“jones”,它应该获取以下记录。我遇到了 CONNECT BY 和 START WITH 子句的问题。我还认为 menu_items 和 role_menu_items 表之间存在一些 JOIN 问题。

对于用户及其相应的角色,我需要检查以下数据

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');
4

1 回答 1

2

糟糕的计划,但有可能

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.反向层次查询


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. reverse(反向层次查询)


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)
于 2012-05-22T05:15:42.350 回答