oracle中如何逐列比较两个表

发布于 2024-09-28 04:29:44 字数 157 浏览 4 评论 0原文

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

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

I have two similar tables in oracle in two different databases.
For example : my table name is EMPLOYEE and primary key is employee id. The same table with same columns(say 50 columns are is avlbl in two databases and two databases are linked.

I want to compare these two tables column by column and find out which records are not matching. i want the specific column in each row in two tables that are not matching.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

慢慢从新开始 2024-10-05 04:29:44
select *
from 
(
( select * from TableInSchema1
  minus 
  select * from TableInSchema2)
union all
( select * from TableInSchema2
  minus
  select * from TableInSchema1)
)

如果你想通过查询解决这个问题,应该可以解决这个问题

select *
from 
(
( select * from TableInSchema1
  minus 
  select * from TableInSchema2)
union all
( select * from TableInSchema2
  minus
  select * from TableInSchema1)
)

should do the trick if you want to solve this with a query

北方的巷 2024-10-05 04:29:44

作为一种替代方案,它可以避免对每个表进行两次完整扫描,并且还为您提供了一种简单的方法来判断哪个表比另一个表具有更多具有值组合的行:

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

As an alternative which saves from full scanning each table twice and also gives you an easy way to tell which table had more rows with a combination of values than the other:

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

Credit goes here: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1417403971710

南风几经秋 2024-10-05 04:29:44

它不会很快,而且你需要输入很多内容(除非你从 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       

It won't be fast, and there will be a lot for you to type (unless you generate the SQL from user_tab_columns), but here is what I use when I need to compare two tables row-by-row and column-by-column.

The query will return all rows that

  • Exists in table1 but not in table2
  • Exists in table2 but not in table1
  • Exists in both tables, but have at least one column with a different value

(common identical rows will be excluded).

"PK" is the column(s) that make up your primary key.
"a" will contain A if the present row exists in table1.
"b" will contain B if the present row exists in table2.

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 ...;

Edit
Added example code to show the difference described in comment.
Whenever one of the values contains NULL, the result will be different.

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       
爱殇璃 2024-10-05 04:29:44

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

Try to use 3rd party tool, such as SQL Data Examiner which compares Oracle databases and shows you differences.

断桥再见 2024-10-05 04:29:44

使用 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); 

该查询执行速度很快。您还可以在选择查询中添加任意数量的列。
唯一的问题是两个表应该具有完全相同的表结构才能执行。

Using the minus operator was working but also it was taking more time to execute which was not acceptable.
I have a similar kind of requirement for data migration and I used the NOT IN operator for that.
The modified query is :

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); 

This query executed fast. Also you can add any number of columns in the select query.
Only catch is that both tables should have the exact same table structure for this to be executed.

素食主义者 2024-10-05 04:29:44
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;
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;
め可乐爱微笑 2024-10-05 04:29:44

使用完整外连接 -- 但不会显示 - 如果不匹配 -

SQL> desc aaa - 它是一张桌子
名字为空?输入


A1 号码
B1 VARCHAR2(10)

SQL> desc aaav -它是一个视图
名字为空?输入


A1 号码
B1 VARCHAR2(10)

SQL> select a.column_name,b.column_name from dba_tab_columns a full external join dba_tab_columns b on a.column_name=b.column_name where a.TABLE_NAME='AAA' and B.table_name='AAAV';

COLUMN_NAME COLUMN_NAME


A1 A1
B1 B1

Used full outer join -- But it will not show - if its not matched -

SQL> desc aaa - its a table
Name Null? Type


A1 NUMBER
B1 VARCHAR2(10)

SQL> desc aaav -its a view
Name Null? Type


A1 NUMBER
B1 VARCHAR2(10)

SQL> select a.column_name,b.column_name from dba_tab_columns a full outer join dba_tab_columns b on a.column_name=b.column_name where a.TABLE_NAME='AAA' and B.table_name='AAAV';

COLUMN_NAME COLUMN_NAME


A1 A1
B1 B1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文