2014-02-15 20 views
0

我有複雜的層次結構,其中一個人可以成爲團隊的團隊領導或其他團隊的團隊成員。下面我在sql中創建了簡單的結構:Oracle - 具有複雜用戶結構的遞歸SQL

CREATE TABLE USERR (
    ID INTEGER NOT NULL, 
    NAME VARCHAR(100) 
); 

Create TABLE TEAM(
    ID INTEGER NOT NULL, 
    NAME VARCHAR(100) 
); 

CREATE TABLE ROLE_TYPE(
    ID INTEGER NOT NULL, 
    NAME VARCHAR(100) 
); 

CREATE TABLE ROLEE(
    ID INTEGER NOT NULL, 
    NAME VARCHAR(100), 
    ROLE_TYPE_ID INTEGER 
); 

CREATE TABLE POSITIONN(
    ID INTEGER NOT NULL, 
    TEAM_ID INTEGER, 
    USER_ID INTEGER, 
    ROLE_ID INTEGER 
); 

INSERT INTO USERR (ID,NAME) VALUES (1,'User 1'); 
INSERT INTO USERR (ID,NAME) VALUES (2,'User 2'); 
INSERT INTO USERR (ID,NAME) VALUES (3,'User 3'); 
INSERT INTO USERR (ID,NAME) VALUES (4,'User 4'); 
INSERT INTO USERR (ID,NAME) VALUES (5,'User 5'); 
INSERT INTO USERR (ID,NAME) VALUES (6,'User 6'); 
INSERT INTO USERR (ID,NAME) VALUES (7,'User 7'); 
INSERT INTO USERR (ID,NAME) VALUES (8,'User 8'); 

INSERT INTO ROLE_TYPE (ID,NAME) VALUES (1,'Leader'); 
INSERT INTO ROLE_TYPE (ID,NAME) VALUES (2,'Member'); 

INSERT INTO ROLEE (ID,NAME, ROLE_TYPE_ID) VALUES (1,'Role 1',1); 
INSERT INTO ROLEE (ID,NAME, ROLE_TYPE_ID) VALUES (2,'Role 1',2); 
INSERT INTO ROLEE (ID,NAME, ROLE_TYPE_ID) VALUES (3,'Role 2',1); 
INSERT INTO ROLEE (ID,NAME, ROLE_TYPE_ID) VALUES (4,'Role 2',2); 
INSERT INTO ROLEE (ID,NAME, ROLE_TYPE_ID) VALUES (5,'Role 3',1); 
INSERT INTO ROLEE (ID,NAME, ROLE_TYPE_ID) VALUES (6,'Role 3',2); 
INSERT INTO ROLEE (ID,NAME, ROLE_TYPE_ID) VALUES (7,'Role 4',1); 
INSERT INTO ROLEE (ID,NAME, ROLE_TYPE_ID) VALUES (8,'Role 4',2); 


INSERT INTO TEAM (ID,NAME) VALUES (1,'Team 1'); 
INSERT INTO TEAM (ID,NAME) VALUES (2,'Team 2'); 
INSERT INTO TEAM (ID,NAME) VALUES (3,'Team 3'); 
INSERT INTO TEAM (ID,NAME) VALUES (4,'Team 4'); 
INSERT INTO TEAM (ID,NAME) VALUES (5,'Team 5'); 

-- user 1 is leader of team 1 - role 1 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (1,1,1,1); 

-- user 2 is member of team 1 - role 1 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (2,1,2,2); 

-- user 2 is leader of team 2 - role 2 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (3,2,2,3); 

-- user 3 is member of team 2 - role 2 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (4,2,3,4); 

-- user 3 is leader of team 3 - role 3 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (5,3,3,5); 

-- user 4 is member of team 2 - role 2 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (6,2,4,4); 

-- user 5 is member of team 3 - role 3 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (7,3,5,6); 

-- user 5 is leader of team 4 - role 4 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (8,4,5,7); 

-- user 6 is member of team 4 - role 4 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (9,4,6,8); 

-- user 7 is member of team 4 - role 4 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (10,4,7,8); 

-- user 4 is leader of team 5 - role 3 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (11,5,4,5); 

-- user 8 is member of team 5 - role 4 
INSERT INTO POSITIONN (ID,TEAM_ID,USER_ID,ROLE_ID) VALUES (12,5,8,6); 

問題是,如果有可能使用connect by或with with structure來獲得層次結構嗎?

我已經試過這樣的事情,但很明顯,我無法找到邏輯條件以創建層次結構這是行不通的:

with q(name, id, parent_id, parent_name) as (
    select 
     USERr.name, USERR.id, 
     null as parent_id, null as parent_name 
    from USERR, TEAM, ROLE_TYPE, ROLEE, POSITIONN 
    where USERR.ID = POSITIONN.USER_ID 
      AND POSITIONN.TEAM_ID = TEAM.ID 
      AND ROLE_TYPE.ID = ROLEE.ROLE_TYPE_ID 
      AND POSITIONN.ROLE_ID = ROLEE.ID 
      AND ROLE_TYPE.NAME = 'Leader' 
      AND USERR.id = 1 
    union all 
    select 
     USERR.name, USERR.id, 
     q.id as parent_id, q.name as parent_name 
    from USERR, TEAM, ROLE_TYPE, ROLEE, POSITIONN, q 
    where USERR.ID = POSITIONN.USER_ID 
      AND POSITIONN.TEAM_ID = TEAM.ID 
      AND ROLE_TYPE.ID = ROLEE.ROLE_TYPE_ID 
      AND POSITIONN.ROLE_ID = ROLEE.ID 
      AND ROLE_TYPE.NAME = 'Member' 
      AND USERR.ID = q.id 
) 
select * from q 

是否有可能接收這些都是用戶的結果在ie用戶3?所以它應該返回:用戶5,用戶6和用戶7,但不會返回用戶8,因爲它不在用戶4之下?

我想,如果我想採取這種數據我需要寫一個函數來做到這一點,我是對的?

回答

1

這將是更好地得到在位置表領導和下屬之間的經典親子關係(如經理標識列)。我試圖讓東西,但因爲這種關係是隱含的,我可以錯過的東西 - 所以下面的代碼只是一個想法:

SQL> SELECT u.name, PRIOR u.name manager FROM 
    2 POSITIONN p 
    3 , USERR u 
    4 , TEAM t 
    5 , ROLEE r 
    6 , ROLE_TYPE rt 
    7 WHERE p.user_id = u.id 
    8 AND p.team_id = t.id 
    9 AND p.role_id = r.id 
10 AND r.role_type_id = rt.id 
11 AND (u.name != PRIOR u.name) 
12 START WITH u.name = 'User 3' AND rt.name = 'Leader' 
13 CONNECT BY (PRIOR t.id = t.id AND rt.name = 'Member' 
14 AND PRIOR rt.name = 'Leader') OR 
15 (PRIOR u.id = u.id AND rt.name = 'Leader' 
16 AND PRIOR rt.name = 'Member') 
17/

NAME     MANAGER              
-------------------- --------------------          
User 5    User 3              
User 6    User 5              
User 7    User 5