web-dev-qa-db-ja.com

Oracleで列ごとに2つのテーブルを比較する方法

2つの異なるデータベースのOracleに2つの類似したテーブルがあります。例:テーブル名はEMPLOYEEで、主キーは従業員IDです。同じ列を持つ同じテーブル(たとえば、50列は2つのデータベースでavlblであり、2つのデータベースがリンクされています)。

これら2つのテーブルを列ごとに比較して、どのレコードが一致しないかを調べます。一致しない2つのテーブルの各行に特定の列が必要です。

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

これをクエリで解決したい場合は、トリックを行う必要があります

16
mcabral

別の方法として、各テーブルを2回フルスキャンする必要がなくなり、どのテーブルに他の値よりも値の組み合わせが多い行があるかを簡単に確認できます。

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:141740397171

5

これは高速ではなく、入力することがたくさんあります(user_tab_columnsからSQLを生成しない限り)が、これは、2つのテーブルを行ごとと列ごとに比較する必要があるときに使用するものです。カラム。

クエリはすべての行を返します

  • Table1には存在するがtable2には存在しない
  • Table2には存在するが、table1には存在しない
  • 両方のテーブルに存在しますが、値が異なる列が少なくとも1つあります

(一般的に同一の行は除外されます)。

「PK」は、主キーを構成する列です。現在の行がtable1に存在する場合、「a」にはAが含まれます。現在の行がtable2に存在する場合、「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       
1
Ronnis

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

このクエリは高速に実行されました。また、選択クエリに任意の数の列を追加できます。唯一の問題は、これを実行するには、両方のテーブルがまったく同じテーブル構造である必要があるということです。

0
AKS

Oracleデータベースを比較して違いを示す SQL Data Examiner などのサードパーティツールを使用してみてください。

0
SQLDev
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;
0
Ahmed Bilal

完全外部結合を使用-ただし、表示されません-一致しない場合-

SQL> desc aaa-テーブルの名前がnullですか?タイプ


A1 NUMBER B1 VARCHAR2(10)

SQL> desc aaav-そのビューName Null?タイプ


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

0
Vasanth Raju