Прошу прощения, если очень похожая задачка обсуждалась - поиском не нашел.
Постановка проста.
Имеются таблички:
1. "Пользователи".create table t_users(Nomer int, Text varchar2(20));
insert into t_users values (1, 'Max');
alter table t_users
add constraint pk_t_users primary key (Nomer); |
2. "Группы пользователей".
create table t_usersgr(Nomer int, Text varchar2(20), Parent int);
insert into t_usersgr values (100, 'Group 1', null);
insert into t_usersgr values (200, 'Group 1-1', 100);
insert into t_usersgr values (300, 'Group 2', null);
insert into t_usersgr values (400, 'Group 3', 200);
alter table t_usersgr
add constraint pk_t_usersgr primary key (Nomer); |
Группы образуют иерархическую структуру, для этого, собственно, и нужно поле Parent. Считается, что если пользователь является членом некоторой группы, то он также является членом всех родительских групп.
3. "Членство в группах".create table t_groupsm(Nomer int, NomerGr int);
insert into t_groupsm values (1, 200);
insert into t_groupsm values (1, 300);
alter table t_groupsm
add constraint pk_t_groupsm primary key (Nomer, NomerGr); |
Собственно, вопрос, наверное, уже ясен: необходимо написать запрос, который покажет членство пользователей в группах
с учетом иерархии групп.
Лично мне пока не придумывается ничего, кроме как поступить так:
SQL> select distinct m.nomer, g.nomer as NomerGr
2 from t_groupsm m,
3 (
4 select t.*, sys_connect_by_path(t.nomer, '\') || '\' path
5 from t_usersgr t
6 connect by prior t.parent = t.nomer
7 ) g
8 where instr(g.path, '\' || to_char(m.nomergr) || '\') <=
9 instr(g.path, '\' || to_char(g.nomer) || '\') and
10 instr(g.path, '\' || to_char(m.nomergr) || '\') <> 0;
NOMER NOMERGR
---------- ----------
1 100
1 200
1 300 |
Кто сможет подсказать, как это сделать еще элегантнее и проще - тому большое спасибо и много пива

Спасибо заранее.