2つの異なるデータベースのOracleに2つの類似したテーブルがあります。例:テーブル名はEMPLOYEEで、主キーは従業員IDです。同じ列を持つ同じテーブル(たとえば、50列は2つのデータベースでavlblであり、2つのデータベースがリンクされています)。
これら2つのテーブルを列ごとに比較して、どのレコードが一致しないかを調べます。一致しない2つのテーブルの各行に特定の列が必要です。
select *
from
(
( select * from TableInSchema1
minus
select * from TableInSchema2)
union all
( select * from TableInSchema2
minus
select * from TableInSchema1)
)
これをクエリで解決したい場合は、トリックを行う必要があります
別の方法として、各テーブルを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
これは高速ではなく、入力することがたくさんあります(user_tab_columnsからSQLを生成しない限り)が、これは、2つのテーブルを行ごとと列ごとに比較する必要があるときに使用するものです。カラム。
クエリはすべての行を返します
(一般的に同一の行は除外されます)。
「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
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);
このクエリは高速に実行されました。また、選択クエリに任意の数の列を追加できます。唯一の問題は、これを実行するには、両方のテーブルがまったく同じテーブル構造である必要があるということです。
Oracleデータベースを比較して違いを示す SQL Data Examiner などのサードパーティツールを使用してみてください。
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;
完全外部結合を使用-ただし、表示されません-一致しない場合-
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