Check if tables are identical using SQL in Oracle

爱⌒轻易说出口 提交于 2019-12-10 21:58:43

问题


I was asked this question during an interview for a Junior Oracle Developer position, the interviewer admitted it was a tough one:

Write a query/queries to check if the table 'employees_hist' is an exact copy of the table 'employees'. Any ideas how to go about this?

EDIT: Consider that tables can have duplicate records so a simple MINUS will not work in this case.

EXAMPLE

EMPLOYEES

NAME
--------
Jack Crack
Jack Crack
Jill Hill

These two would not be identical.

EMPLOYEES_HIST

NAME
--------
Jack Crack
Jill Hill
Jill Hill

回答1:


One possible solution, which caters for duplicates, is to create a subquery which does a UNION on the two tables, and includes the number of duplicates contained within each table by grouping on all the columns. The outer query can then group on all the columns, including the row count column. If the table match, there should be no rows returned:

create table employees (name varchar2(100));
create table employees_hist (name varchar2(100));

insert into employees values ('Jack Crack');
insert into employees values ('Jack Crack');
insert into employees values ('Jill Hill');
insert into employees_hist values ('Jack Crack');
insert into employees_hist values ('Jill Hill');
insert into employees_hist values ('Jill Hill');


with both_tables as
(select name, count(*) as row_count
 from employees
 group by name
union all
 select name, count(*) as row_count
 from employees_hist
 group by name)
select name, row_count from both_tables
group by name, row_count having count(*) <> 2;

gives you:

Name        Row_count
Jack Crack  1
Jack Crack  2
Jill Hill   1
Jill Hill   2

This tells you that both names appear once in one table and twice in the other, and therefore the tables don't match.




回答2:


If the tables have the same columns, you can use this; this will return no rows if the rows in both tables are identical:

(
select * from test_data_01
minus
select * from test_data_02
)
union
(
select * from test_data_02
minus
select * from test_data_01
);



回答3:


Identical regarding what? Metadata or the actual table data too?

Anyway, use MINUS.

select * from table_1
MINUS
select * from table_2

So, if the two tables are really identical, i.e. the metadata and the actual data, it would return no rows. Else, it would prove that the data is different.

If, you receive an error, it would mean the metadata itself is different.

Update If the data is not same, and that one of the table has duplicates.

Just select the unique records from one of the table, and simply apply MINUS against the other table.




回答4:


select name, count(*) n from EMPLOYEES group by name
minus
select name, count(*) n from EMPLOYEES_HIST group by name
union all ( 
select name, count(*) n from EMPLOYEES_HIST group by name
minus
select name, count(*) n from EMPLOYEES group by name)



回答5:


You could merge the two tables and then subtract one of the tables from the result. If the result of the subtraction is an empty table then you know that the the tables must be the same since merge had no effect (every row and column were effectively the same)

How do I merge two tables with different column number while removing duplicates?

That link provides a good way to merge the two tables without duplicates without knowing what the columns are.




回答6:


Ensure the rows are unique by adding a pseudo column

WITH t1 AS
  (SELECT <All_Columns>
        , row_number() OVER
            (PARTITION BY <All_Columns>
             ORDER BY <All_Columns>) row_num
   FROM employees)
, t2 AS
  (SELECT <All_Columns>
        , row_number() OVER
            (PARTITION BY <All_Columns>
             ORDER BY <All_Columns>) row_num
   FROM employees_hist)
(SELECT *
 FROM t1
 MINUS
 SELECT *
 FROM t2
UNION ALL
(SELECT *
 FROM t1
 MINUS
 SELECT *
 FROM t2)



回答7:


Use row_number to make sure there are no duplicate rows. Now you can use minus and if there are no results, the tables are identical.

SELECT ROW_NUMBER() OVER (Order By Name), *
FROM tab1
MINUS
SELECT ROW_NUMBER() OVER (Order By Name), *
FROM tab2


来源:https://stackoverflow.com/questions/26511527/check-if-tables-are-identical-using-sql-in-oracle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!