加入表列具有混合值的多个表

时间:2014-06-27 11:10:08

标签: sql join oracle11g

嗨伙计们!在过去的几天里,我一直在寻找网络和SO的解决方案。这是我的第一个问题所以请耐心等待:)。

在解释之前我想道歉,如果它太简单了,但我已经尝试了所有我能想到的东西而且我什么都没有。所以,让我们开始:))

问题是在t3_access.auth_id中有像user_id和group_id这样的值,所以我需要编写一个查询,列出t3_access.auth_id列中列出的所有用户以及组中的用户t3_access.auth_id。

是否可以区分某些查询中与user_id或group_id连接的用户?任何帮助都非常受欢迎。

这是sqlfiddle链接:http://sqlfiddle.com/#!2/b6dd7/5

我有四个表格结构:

t1_users (user_id, name, pwd_opts)
t2_connections (user_id, group_id, conn_opts)
t3_access (auth_id, class_name, gr_name)
t4_groups (group_id, group_name)

以下是示例数据:

create table t1_users ("user_id" varchar2(10), "name" varchar2(10), "pwd_opts" varchar2(10));
create table t2_connections ("user_id" varchar2(10), "group_id" varchar2(10), "conn_opts" varchar2(10));
create table t3_access ("auth_id" varchar2(10), "class_name" varchar2(10), "gr_name" varchar2(10), "access" varchar2(10));

create table t4_groups ("GROUP_ID" varchar2(10), "group_name" varchar2(20));

insert into t1_users ("user_id", "name", "pwd_opts", "usr_opts") values ('Peter','Peter Pan','OK','RESTRICTED');
insert into t1_users ("user_id", "name", "pwd_opts", "usr_opts") values ('George','George Michael','OK','NORMAL');
insert into t1_users ("user_id", "name", "pwd_opts", "usr_opts") values ('Danny','Danny Boy','LOCK','SPECIAL');
insert into t1_users ("user_id", "name", "pwd_opts", "usr_opts") values ('John','John Wayne','OK','NORMAL');


insert into t2_connections (user_id, group_id, conn_opts) values('Peter','GROUP1','NORMAL');
insert into t2_connections (user_id, group_id, conn_opts) values('Peter','GROUP2','NORMAL');
insert into t2_connections (user_id, group_id, conn_opts) values('George','GROUP2','SPECIAL');
insert into t2_connections (user_id, group_id, conn_opts) values('Danny','GROUP2','NORMAL');
insert into t2_connections (user_id, group_id, conn_opts) values('John','GROUP3','NORMAL');


insert into t3_access(auth_id, class_name, gr_name, access) values('Peter','class1','PROFILE1','READ');
insert into t3_access(auth_id, class_name, gr_name, access) values('GROUP2','class1','PROFILE2','READ');
insert into t3_access(auth_id, class_name, gr_name, access) values('GROUP3','class3','PROFILE3','UPDATE');
insert into t3_access(auth_id, class_name, gr_name, access) values('George','class2','PROFILE2','EXECUTE');
insert into t3_access(auth_id, class_name, gr_name, access) values('John','class4','PROFILE4','NONE');

insert into t4_groups (group_id, "group_name") VALUES ('GROUP1', 'first group');
insert into t4_groups (group_id, "group_name") VALUES ('GROUP2', 'second group');
insert into t4_groups (group_id, "group_name") VALUES ('GROUP3', 'third group');

我尝试过的事情(我已尝试过两次选择之间的UNION,IN,EXISTS)但没有任何结果可以让我得到预期的结果:

select t2_connections.*, t3_access.*
from t2_connections
join t3_access ON t2_connections.group_id = t3_access.auth_id 
where group_id IN (select auth_id from t3_access where auth_id like 'GROUP%');

select t2_connections.*, t3_access.*
from t3_access
join t2_connections ON t3_access.auth_id = t2_connections.user_id
where auth_id IN (select auth_id from t3_access where user_id like 'George' or auth_id like 'Danny' or auth_id like 'Peter' or auth_id like 'John' );

......我也尝试过:

select t1_users.user_id, t1_users.name, t1_users.pwd_opts, t1_users.usr_opts,
       t2_connections.group_id, t2_connections.conn_opts, t3_access.class_name, t3_access.gr_name,
       t3_access.access
from t2_connections
join t1_users on t2_connections.user_id = t1_users.user_id
join t4_groups on t2_connections.group_id = t4_groups.group_id
join t3_access on t2_connections.group_id = t3_access.auth_id
where exists (select * from t3_access where t3_access.auth_id = t2_connections.user_id);
union 
select t1_users.user_id, t1_users.name, t1_users.pwd_opts, t1_users.usr_opts,
       t2_connections.group_id, t2_connections.conn_opts, t3_access.class_name, t3_access.gr_name,
       t3_access.access
from t2_connections
join t1_users on t2_connections.user_id = t1_users.user_id
join t4_groups on t2_connections.group_id = t4_groups.group_id
join t3_access on t2_connections.group_id = t3_access.auth_id
where exists (select * from t3_access where t3_access.auth_id = t2_connections.group_id);

预期输出应如下所示:

user_id|name |pwd_|usr_opts    |group_id|conn_opt|cl_name |gr_name   |access
Peter | bla1 | ok | restricted | group1 | normal | class1 | profile1 | read
Peter | bla1 | ok | restricted | group2 | normal | class1 | profile2 | read
George| bla3 | ok | normal     | group2 | special| class2 | profile2 | execute
George| bla3 | ok | normal     | group2 | special| class1 | profile2 | read
Danny | bla4 |lock| special    | group2 | normal | class1 | profile2 | read
John  | bla5 | ok | normal     | group2 | normal | class4 | profile4 | none
John  | bla5 | ok | noraml     | group3 | normal | class3 | profile3 | update

1 个答案:

答案 0 :(得分:0)

将您的示例设置修改如下...

create table t1_users (user_id varchar2(10), name varchar2(20), pwd_opts varchar2(10), usr_opts varchar2(15));
create table t2_connections (user_id varchar2(10), group_id varchar2(10), conn_opts varchar2(10));
create table t3_access (auth_id varchar2(10), class_name varchar2(10), gr_name varchar2(10), acces varchar2(10));
create table t4_groups (group_id varchar2(10), group_name varchar2(20));

insert into t1_users (user_id, name, pwd_opts, usr_opts) values ('Peter','Peter Pan','OK','RESTRICTED');
insert into t1_users (user_id, name, pwd_opts, usr_opts) values ('George','George Michael','OK','NORMAL');
insert into t1_users (user_id, name, pwd_opts, usr_opts) values ('Danny','Danny Boy','LOCK','SPECIAL');
insert into t1_users (user_id, name, pwd_opts, usr_opts) values ('John','John Wayne','OK','NORMAL');

insert into t2_connections (user_id, group_id, conn_opts) values('Peter','GROUP1','NORMAL');
insert into t2_connections (user_id, group_id, conn_opts) values('Peter','GROUP2','NORMAL');
insert into t2_connections (user_id, group_id, conn_opts) values('George','GROUP2','SPECIAL');
insert into t2_connections (user_id, group_id, conn_opts) values('Danny','GROUP2','NORMAL');
insert into t2_connections (user_id, group_id, conn_opts) values('John','GROUP3','NORMAL');

insert into t3_access(auth_id, class_name, gr_name, acces) values('Peter','class1','PROFILE1','READ');
insert into t3_access(auth_id, class_name, gr_name, acces) values('GROUP2','class1','PROFILE2','READ');
insert into t3_access(auth_id, class_name, gr_name, acces) values('GROUP3','class3','PROFILE3','UPDATE');
insert into t3_access(auth_id, class_name, gr_name, acces) values('George','class2','PROFILE2','EXECUTE');
insert into t3_access(auth_id, class_name, gr_name, acces) values('John','class4','PROFILE4','NONE');

insert into t4_groups (group_id, group_name) VALUES ('GROUP1', 'first group');
insert into t4_groups (group_id, group_name) VALUES ('GROUP2', 'second group');
insert into t4_groups (group_id, group_name) VALUES ('GROUP3', 'third group');

commit;

我能得到的最接近的是:

with all_users$ as (
    select
        U.user_id, U.name, U.pwd_opts, U.usr_opts, C.group_id, C.conn_opts, A.class_name, A.gr_name, A.acces
    from t3_access A
        join t1_users U on U.user_id = A.auth_id
        join t2_connections C on C.user_id = A.auth_id
),
all_groups$ as (
    select
        U.user_id, U.name, U.pwd_opts, U.usr_opts, C.group_id, C.conn_opts, A.class_name, A.gr_name, A.acces
    from t3_access A
        join t2_connections C on C.group_id = A.auth_id
        join t1_users U on U.user_id = C.user_id
    where exists (
            select 1
            from t4_groups G
            where G.group_id = A.auth_id
        )
)
select *
from all_users$ AU
where not exists (
        select 1
        from all_groups$ Gx
        where Gx.user_id = AU.user_id
            and Gx.group_id = AU.group_id
            and Gx.class_name = AU.class_name
    )
--
union all
--
select *
from all_groups$ AG
;