使用Oracle中的SQL检查表是否相同

时间:2014-10-22 15:43:17

标签: sql oracle compare

在接受甲骨文初级开发人员职位的采访时,我被问到这个问题,面试官承认这是一个艰难的问题:

撰写查询/查询以检查表格' employees_hist'是表格'员工的精确副本。任何想法如何去做?

编辑:考虑到表可以有重复的记录,因此在这种情况下简单的MINUS不起作用。

实施例

EMPLOYEES

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

这两个不一样。

EMPLOYEES_HIST

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

7 个答案:

答案 0 :(得分:2)

如果表格具有相同的列,则可以使用此列;如果两个表中的行相同,则不返回任何行:

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

答案 1 :(得分:1)

相同的是什么?元数据或实际的表数据呢?

无论如何,请使用MINUS

select * from table_1 MINUS Select * from table_2 `

因此,如果两个表真的相同,即元数据和实际数据,它将不返回任何行。否则,它将证明数据不同。

如果您收到错误,则表示元数据本身不同。

更新如果数据不相同,并且其中一个表有重复数据。

只需从其中一个表中选择唯一记录,然后只需将MINUS应用于另一个表。

答案 2 :(得分:1)

一个可能的解决方案,它可以创建一个子查询,它在两个表上执行UNION,并通过对所有列进行分组来包含每个表中包含的重复数。然后,外部查询可以对所有列进行分组,包括行计数列。如果表匹配,则不应返回任何行:

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;

给你:

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

这告诉您两个名字在一个表格中出现一次,在另一个表格中出现两次,因此表格不匹配。

答案 3 :(得分:1)

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)

答案 4 :(得分:0)

您可以合并两个表,然后从结果中减去其中一个表。如果减法的结果是一个空表,那么你知道表必须是相同的,因为合并没有效果(每行和每列实际上是相同的)

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

该链接提供了一种很好的方法来合并两个表而无需重复,而不知道列是什么。

答案 5 :(得分:0)

使用row_number确保没有重复的行。现在你可以使用减号,如果没有结果,表格是相同的。

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

答案 6 :(得分:0)

通过添加伪列

确保行是唯一的
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)