连接具有不同行数的表而不重复
Joining tables with different number of rows without duplicates
我有一个已经很复杂的 SQL 语句创建了 table 个拥有 CONNECT
、APPUSER
或两者权利的用户:
(SELECT b.grantee AS "Username", A.granted_role AS "Connect", b.granted_role AS "APPUSER" FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
RIGHT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
UNION
(SELECT A.grantee, A.granted_role, b.granted_role FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
LEFT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
这会产生如下内容:
Username Connect APPUSER
--------- --------- ---------
Sue CONNECT APPUSER
Bob (null) APPUSER
Joe CONNECT (null)
我想用all_users
table,来显示没有这两种权利的用户。all_users
table 显示数据库中的每个用户。
我已经尝试在 SQL 语句的末尾添加几种类型的连接来实现这一点。我得到的最接近的是添加:
UNION
(SELECT username, NULL, NULL FROM all_users)
这将生成一个列表,其中每个用户显示两次,但显示的用户没有任何权利:
Username Connect APPUSER
--------- --------- ---------
Amy (null) (null)
Sue CONNECT APPUSER
Sue (null) (null)
Bob (null) APPUSER
Bob (null) (null)
Joe CONNECT (null)
Joe (null) (null)
我尝试添加 where username = a.grantee
,但这不适用于联合会。如果我尝试用任何 JOIN
替换 UNION
,例如添加:
FULL OUTER JOIN
SELECT username, NULL, NULL FROM ALL_USERS
on username = a.grantee;
我收到错误:
"SQL command not properly ended"
您的查询似乎比必要的要复杂得多。这是一种方法:
select grantee,
max(case when granted_role = 'CONNECT' then granted_role end) as "connect",
max(case when granted_role = 'APPUSER' then granted_role end) as "appuser"
from dba_role_privs
group by grantee;
如果有些用户根本没有角色,那么您将需要 all_users
table。
编辑:
只需使用 left join
:
select au.userName,
max(case when granted_role = 'CONNECT' then granted_role end) as "connect",
max(case when granted_role = 'APPUSER' then granted_role end) as "appuser"
from all_users au join
dba_role_privs rp
on au.userName = rp.grantee
group by au.userName;
我不太确定我理解第一个查询。当您可以使用 PIVOT 时,您似乎正在做一些非常复杂的事情。但是,如果它工作正常,那么您应该可以这样做:
SELECT username
FROM ALL_USERS
WHERE username NOT IN (
(SELECT DISTINCT b.grantee AS "Username", A.granted_role AS "Connect", b.granted_role AS "APPUSER" FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
RIGHT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
UNION
(SELECT A.grantee, A.granted_role, b.granted_role FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
LEFT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
)
使用以下查询。让我知道这个是否奏效。您需要在 where 子句中添加 dp1.granted_role is null and dp2.granted_role is null.
select au.username,
dp1.granted_role,
dp2.granted_role
from all_users au
left join dba_role_privs drp1 on drp1.grantee=au.username and drp1.granted_role='CONNECT'
left join dba_role_privs drp2 on drp2.grantee=au.username and drp2.granted_role='APPUSER'
我有一个已经很复杂的 SQL 语句创建了 table 个拥有 CONNECT
、APPUSER
或两者权利的用户:
(SELECT b.grantee AS "Username", A.granted_role AS "Connect", b.granted_role AS "APPUSER" FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
RIGHT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
UNION
(SELECT A.grantee, A.granted_role, b.granted_role FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
LEFT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
这会产生如下内容:
Username Connect APPUSER
--------- --------- ---------
Sue CONNECT APPUSER
Bob (null) APPUSER
Joe CONNECT (null)
我想用all_users
table,来显示没有这两种权利的用户。all_users
table 显示数据库中的每个用户。
我已经尝试在 SQL 语句的末尾添加几种类型的连接来实现这一点。我得到的最接近的是添加:
UNION
(SELECT username, NULL, NULL FROM all_users)
这将生成一个列表,其中每个用户显示两次,但显示的用户没有任何权利:
Username Connect APPUSER
--------- --------- ---------
Amy (null) (null)
Sue CONNECT APPUSER
Sue (null) (null)
Bob (null) APPUSER
Bob (null) (null)
Joe CONNECT (null)
Joe (null) (null)
我尝试添加 where username = a.grantee
,但这不适用于联合会。如果我尝试用任何 JOIN
替换 UNION
,例如添加:
FULL OUTER JOIN
SELECT username, NULL, NULL FROM ALL_USERS
on username = a.grantee;
我收到错误:
"SQL command not properly ended"
您的查询似乎比必要的要复杂得多。这是一种方法:
select grantee,
max(case when granted_role = 'CONNECT' then granted_role end) as "connect",
max(case when granted_role = 'APPUSER' then granted_role end) as "appuser"
from dba_role_privs
group by grantee;
如果有些用户根本没有角色,那么您将需要 all_users
table。
编辑:
只需使用 left join
:
select au.userName,
max(case when granted_role = 'CONNECT' then granted_role end) as "connect",
max(case when granted_role = 'APPUSER' then granted_role end) as "appuser"
from all_users au join
dba_role_privs rp
on au.userName = rp.grantee
group by au.userName;
我不太确定我理解第一个查询。当您可以使用 PIVOT 时,您似乎正在做一些非常复杂的事情。但是,如果它工作正常,那么您应该可以这样做:
SELECT username
FROM ALL_USERS
WHERE username NOT IN (
(SELECT DISTINCT b.grantee AS "Username", A.granted_role AS "Connect", b.granted_role AS "APPUSER" FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
RIGHT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
UNION
(SELECT A.grantee, A.granted_role, b.granted_role FROM
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'CONNECT') A
LEFT OUTER JOIN
(SELECT grantee, granted_role FROM dba_role_privs WHERE granted_role = 'APPUSER') b
ON A.grantee=b.grantee)
)
使用以下查询。让我知道这个是否奏效。您需要在 where 子句中添加 dp1.granted_role is null and dp2.granted_role is null.
select au.username,
dp1.granted_role,
dp2.granted_role
from all_users au
left join dba_role_privs drp1 on drp1.grantee=au.username and drp1.granted_role='CONNECT'
left join dba_role_privs drp2 on drp2.grantee=au.username and drp2.granted_role='APPUSER'