Reputation: 63
I have a database where people regularly create backup tables from existing table which i have to drop after sometime.Is there any query in oracle to find all tables having same structure but different names.
Upvotes: 1
Views: 800
Reputation: 4660
Use aliases of all_tab_columns and join them to all_objects, making sure that the object type is of TABLE. Next, make sure the "matching" table is not itself (object_id are not equal to each other).
Next, count the matching columns with the total columns in each table and compare.
SELECT t1.object_name table_name,
col_ct.total_cols table_total_cols,
t2.object_name matching_table,
COUNT(1) matching_columns_ct
FROM
(SELECT o.object_id,
COUNT(1) total_cols
FROM all_objects o,
all_tab_columns tc
WHERE 1 =1
AND o.object_type = 'TABLE'
AND o.owner = tc.owner
AND o.object_name = tc.table_name
GROUP BY o.object_id
) col_ct,
all_objects t1,
all_objects t2,
all_tab_columns tc1,
all_tab_columns tc2
WHERE 1 =1
AND t1.object_type = 'TABLE'
AND t2.object_type = 'TABLE'
AND t1.owner =
&TableOwner
AND t1.object_name =
&TableName
AND t1.object_id =col_ct.object_id
AND t1.object_id != t2.object_id
AND t1.owner = tc1.owner
AND t1.object_name = tc1.table_name
AND t2.owner = tc2.owner
AND t2.object_name = tc2.table_name
AND tc1.column_name = tc2.column_name
AND tc1.data_type = tc2.data_type
GROUP BY t1.object_name,
col_ct.total_cols,
t2.object_name
HAVING COUNT(1) =col_ct.total_cols
Upvotes: 0
Reputation: 1456
Below query first finds all tables with matching # columns and 32-bit hash of column position+name+data_type. Birthday paradox comes into play here - there's an outside chance of accidental collisions (approaching 50% chance of 1 false positive in a database with 65,000 tables). If you're filtering for user schemas and searching through significantly less than 65,000 total tables, just query T0 directly. Otherwise, remaining SQL will ensure you only get tables with matching column structures.
WITH T AS
(
SELECT OWNER O,
TABLE_NAME N,
SUM(ORA_HASH(COLUMN_ID||COLUMN_NAME||DATA_TYPE,POWER(2,32)-1)) H,
COUNT(*) C
FROM DBA_TABLES
JOIN DBA_TAB_COLUMNS USING (OWNER,TABLE_NAME)
-----------------------------------------------------------------
-- where clause here to limit schemas to user-defined tables
-----------------------------------------------------------------
GROUP BY OWNER, TABLE_NAME
)
SELECT O1, N1, O2, N2
FROM
(
SELECT T1.N N1, T1.O O1, T2.N N2, T2.O O2, C
FROM T T1 JOIN T T2 USING (H, C)
WHERE (T1.N <> T2.N OR T1.O <> T2.O)
) T0
---------------------------------------------------------------------
-- Remaining SQL only needed if false-positives must be avoided
---------------------------------------------------------------------
JOIN DBA_TAB_COLUMNS T1 ON (T0.O1 = T1.OWNER AND T0.N1=T1.TABLE_NAME)
JOIN DBA_TAB_COLUMNS T2 ON (T0.O2 = T2.OWNER AND T0.N2 = T2.TABLE_NAME
AND T2.COLUMN_ID = T1.COLUMN_ID
AND T2.COLUMN_NAME = T1.COLUMN_NAME
AND T2.DATA_TYPE = T1.DATA_TYPE)
GROUP BY O1, N1, O2, N2, C
HAVING COUNT(*) = C
Upvotes: 0
Reputation: 1270713
If you have a particular table, try this to get the count of tables with common column names:
select atc.owner, atc.table_name, count(*) as ColumnsInCommon
from all_tab_columns atc join
all_tab_columns atc1
on atc.column_name = atc1.column_name and
atc1.table_name = YOURTABLENAME and
atc1.owner = YOUROWNER
group by atc.owner, atc.table_name
order by count(*) desc;
This should show your original table on top.
Upvotes: 0