如何一张一张地获取一个用户拥有但不属于其他用户的所有表
How to get all tables owned by one user but not by others, one by one
假定两个用户拥有相同的 table,因为他们都拥有同名的 table。
在我的 Oracle 数据库中,我有 N 个名为 MAIN 的用户,USR_1,USR_2,...,USR_N。用户 MAIN 拥有其他用户拥有的所有 table。但是,它可能有 USR_1 拥有但 USR_2 没有的 table,或者 USR_2048 拥有而 USR_1024 没有,等等。
我想进行查询以检索 MAIN 用户所有但不属于某个用户的所有 table。其实我想一个一个去查,大概是这样的:
获取用户 MAIN 拥有的所有 table 并与 USR_1 进行比较,
获取用户 MAIN 拥有的所有 table 并与 USR_2 进行比较,
...
获取用户 MAIN 拥有的所有 table 并将其与 USR_N、
进行比较
并且 return table 名称包含在 MAIN 中但不包含在该特定用户中。
我都试过:
SELECT TABLE_NAME
FROM DBA_TABLES
WHERE OWNER LIKE 'MAIN'
AND TABLE_NAME NOT IN (SELECT TABLE_NAME
FROM DBA_TABLES
WHERE OWNER LIKE '%USR_%');
SELECT TABLE_NAME
FROM DBA_TABLES
WHERE OWNER LIKE 'MAIN'
AND TABLE_NAME NOT IN (SELECT TABLE_NAME
FROM DBA_TABLES
WHERE OWNER LIKE '%USR_%'
GROUP BY OWNER, TABLE_NAME);
我明白为什么第一个语句不起作用,但我认为可以使用第二个语句。我怎样才能让它成为可能?
我会这样做:
SELECT m.TABLE_NAME, usr_count, owner_list
FROM DBA_TABLES m
LEFT JOIN (SELECT TABLE_NAME, count(*) as usr_count, listagg(OWNER, ',') within group (order by OWNER) as owner_list
FROM DBA_TABLES
WHERE OWNER LIKE 'USR_%'
GROUP BY TABLE_NAME) usr
ON m.TABLE_NAME = usr.TABLE_NAME
WHERE m.OWNER LIKE 'MAIN'
-- hide tables that everyone has
AND coalesce(usr_count,0) < (select count(*) from ALL_USERS where USERNAME like 'USR_%')
;
编辑:实际上,如果您想要一份 没有 的 USR_% 用户的列表,每个 table,anti-join 可能会更好.
SELECT m.TABLE_NAME, listagg(USERNAME, ',') within group (order by USERNAME) as usr_missing_table
FROM DBA_TABLES m
JOIN ALL_USERS a
ON a.USERNAME like 'USR_%'
LEFT JOIN DBA_TABLES usr
ON a.USERNAME = usr.OWNER
AND m.TABLE_NAME = usr.TABLE_NAME
WHERE m.OWNER LIKE 'MAIN'
AND usr.TABLE_NAME is null
GROUP BY m.TABLE_NAME
;
假定两个用户拥有相同的 table,因为他们都拥有同名的 table。
在我的 Oracle 数据库中,我有 N 个名为 MAIN 的用户,USR_1,USR_2,...,USR_N。用户 MAIN 拥有其他用户拥有的所有 table。但是,它可能有 USR_1 拥有但 USR_2 没有的 table,或者 USR_2048 拥有而 USR_1024 没有,等等。
我想进行查询以检索 MAIN 用户所有但不属于某个用户的所有 table。其实我想一个一个去查,大概是这样的:
获取用户 MAIN 拥有的所有 table 并与 USR_1 进行比较, 获取用户 MAIN 拥有的所有 table 并与 USR_2 进行比较, ... 获取用户 MAIN 拥有的所有 table 并将其与 USR_N、
进行比较并且 return table 名称包含在 MAIN 中但不包含在该特定用户中。
我都试过:
SELECT TABLE_NAME
FROM DBA_TABLES
WHERE OWNER LIKE 'MAIN'
AND TABLE_NAME NOT IN (SELECT TABLE_NAME
FROM DBA_TABLES
WHERE OWNER LIKE '%USR_%');
SELECT TABLE_NAME
FROM DBA_TABLES
WHERE OWNER LIKE 'MAIN'
AND TABLE_NAME NOT IN (SELECT TABLE_NAME
FROM DBA_TABLES
WHERE OWNER LIKE '%USR_%'
GROUP BY OWNER, TABLE_NAME);
我明白为什么第一个语句不起作用,但我认为可以使用第二个语句。我怎样才能让它成为可能?
我会这样做:
SELECT m.TABLE_NAME, usr_count, owner_list
FROM DBA_TABLES m
LEFT JOIN (SELECT TABLE_NAME, count(*) as usr_count, listagg(OWNER, ',') within group (order by OWNER) as owner_list
FROM DBA_TABLES
WHERE OWNER LIKE 'USR_%'
GROUP BY TABLE_NAME) usr
ON m.TABLE_NAME = usr.TABLE_NAME
WHERE m.OWNER LIKE 'MAIN'
-- hide tables that everyone has
AND coalesce(usr_count,0) < (select count(*) from ALL_USERS where USERNAME like 'USR_%')
;
编辑:实际上,如果您想要一份 没有 的 USR_% 用户的列表,每个 table,anti-join 可能会更好.
SELECT m.TABLE_NAME, listagg(USERNAME, ',') within group (order by USERNAME) as usr_missing_table
FROM DBA_TABLES m
JOIN ALL_USERS a
ON a.USERNAME like 'USR_%'
LEFT JOIN DBA_TABLES usr
ON a.USERNAME = usr.OWNER
AND m.TABLE_NAME = usr.TABLE_NAME
WHERE m.OWNER LIKE 'MAIN'
AND usr.TABLE_NAME is null
GROUP BY m.TABLE_NAME
;