我有一个复杂的层次结构,一个人可以成为团队的团队领导或其他团队的团队成员。下面我在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 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
是否有可能接收到user3下的所有用户的结果?所以它应该返回:用户5,用户6和用户7,但不会返回用户8,因为它不在用户4下?
我想,如果我想拿这种数据我需要写一个函数来做,我是对的吗?
答案 0 :(得分:1)
最好在位置表(如manager_id列)中获得领导者和下属之间的经典父子关系。我尝试制作一些东西,但因为这种关系是隐含的,我可能会错过一些东西 - 所以下面的代码只是一个想法:
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