如何在oracle中逐列比较两个表

时间:2010-10-20 17:03:40

标签: sql database oracle database-design oracle10g

我在两个不同的数据库中有两个类似的oracle表。 例如:我的表名是EMPLOYEE,主键是员工ID。具有相同列的相同表(例如,50列是两个数据库中的avlbl,并且链接了两个数据库。

我想逐列比较这两个表,找出哪些记录不匹配。我希望两个表中每行中的特定列不匹配。

7 个答案:

答案 0 :(得分:15)

select *
from 
(
( select * from TableInSchema1
  minus 
  select * from TableInSchema2)
union all
( select * from TableInSchema2
  minus
  select * from TableInSchema1)
)
如果你想用查询解决这个问题,那么

应该可以解决这个问题

答案 1 :(得分:4)

作为一种替代方案,可以避免对每个表进行两次全扫描,并且还可以让您轻松地判断哪个表的行数多于另一个表的行数:

SELECT col1
     , col2
     -- (include all columns that you want to compare)
     , COUNT(src1) CNT1
     , COUNT(src2) CNT2
  FROM (SELECT a.col1
             , a.col2
             -- (include all columns that you want to compare)
             , 1 src1
             , TO_NUMBER(NULL) src2
          FROM tab_a a
         UNION ALL
        SELECT b.col1
             , b.col2
             -- (include all columns that you want to compare)
             , TO_NUMBER(NULL) src1
             , 2 src2
          FROM tab_b b
       )
 GROUP BY col1
        , col2
HAVING COUNT(src1) <> COUNT(src2) -- only show the combinations that don't match

信用到这里:http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1417403971710

答案 2 :(得分:1)

尝试使用第三方工具,例如SQL Data Examiner,它可以比较Oracle数据库并显示差异。

答案 3 :(得分:1)

它不会很快,并且你会输入很多东西(除非你从user_tab_columns生成SQL),但是当我需要逐行和列地比较两个表时,我会使用逐列。

查询将返回

的所有行
  • 存在于table1中但不存在于table2中
  • 存在于table2中但不存在于table1
  • 两个表中都存在,但至少有一列具有不同的值

(将排除常见的相同行。)

“PK”是构成主键的列。 如果table1中存在当前行,则“a”将包含A. 如果表2中存在当前行,则“b”将包含B.

select pk
      ,decode(a.rowid, null, null, 'A') as a
      ,decode(b.rowid, null, null, 'B') as b
      ,a.col1, b.col1
      ,a.col2, b.col2
      ,a.col3, b.col3
      ,...
  from table1 a 
  full outer 
  join table2 b using(pk)
 where decode(a.col1, b.col1, 1, 0) = 0
    or decode(a.col2, b.col2, 1, 0) = 0
    or decode(a.col3, b.col3, 1, 0) = 0
    or ...;

修改 添加了示例代码以显示注释中描述的差异。 只要其中一个值包含NULL,结果就会不同。

with a as(
   select 0    as col1 from dual union all
   select 1    as col1 from dual union all
   select null as col1 from dual
)
,b as(
   select 1    as col1 from dual union all
   select 2    as col1 from dual union all
   select null as col1 from dual
)   
select a.col1
      ,b.col1
      ,decode(a.col1, b.col1, 'Same', 'Different') as approach_1
      ,case when a.col1 <> b.col1 then 'Different' else 'Same' end as approach_2       
  from a,b
 order 
    by a.col1
      ,b.col1;    




col1   col1_1   approach_1  approach_2
====   ======   ==========  ==========
  0        1    Different   Different  
  0        2    Different   Different  
  0      null   Different   Same         <--- 
  1        1    Same        Same       
  1        2    Different   Different  
  1      null   Different   Same         <---
null       1    Different   Same         <---
null       2    Different   Same         <---
null     null   Same        Same       

答案 4 :(得分:0)

使用minus运算符正在运行但是它需要更多时间来执行,这是不可接受的。 我对数据迁移有类似的要求,我使用了NOT IN运算符。 修改后的查询是:

select * 
from A 
where (emp_id,emp_name) not in 
   (select emp_id,emp_name from B) 
   union all 
select * from B 
where (emp_id,emp_name) not in 
   (select emp_id,emp_name from A); 

此查询执行得很快。您还可以在选择查询中添加任意数量的列。 只有catch表明两个表应该具有完全相同的表结构才能执行。

答案 5 :(得分:0)

SELECT *
  FROM (SELECT   table_name, COUNT (*) cnt
            FROM all_tab_columns
           WHERE owner IN ('OWNER_A')
        GROUP BY table_name) x,
       (SELECT   table_name, COUNT (*) cnt
            FROM all_tab_columns
           WHERE owner IN ('OWNER_B')
        GROUP BY table_name) y
 WHERE x.table_name = y.table_name AND x.cnt <> y.cnt;

答案 6 :(得分:0)

使用了完整的外部联接-但不会显示-如果不匹配-

SQL> desc aaa-其表  名称为空?输入


A1 NUMBER  B1 VARCHAR2(10)

SQL> desc aaav-它的视图  名称为空?输入


A1 NUMBER  B1 VARCHAR2(10)

SQL>从dba_tab_columns中选择a.column_name,b.column_name到a.column_name = b.column_name上的完整外部联接dba_tab_columns b,其中a.TABLE_NAME ='AAA'和B.table_name ='AAAV';

COLUMN_NAME COLUMN_NAME


A1 A1 B1 B1