web-dev-qa-db-ger.com

So vergleichen Sie zwei Tabellen Spalte für Spalte in Oracle

Ich habe zwei ähnliche Tabellen in Oracle in zwei verschiedenen Datenbanken. Zum Beispiel: Mein Tabellenname ist EMPLOYEE und der Primärschlüssel ist die Mitarbeiter-ID. Dieselbe Tabelle mit den gleichen Spalten (50 Spalten sind in zwei Datenbanken avlbl und zwei Datenbanken sind miteinander verbunden.

Ich möchte diese beiden Tabellen spaltenweise vergleichen und herausfinden, welche Datensätze nicht übereinstimmen. Ich möchte die spezifische Spalte in jeder Zeile in zwei Tabellen, die nicht übereinstimmen.

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

sollte den Trick tun, wenn Sie dies mit einer Abfrage lösen möchten

15
mcabral

Als Alternative, die das vollständige Scannen jeder Tabelle erspart und Sie auf einfache Weise feststellen können, welche Tabelle mehr Zeilen mit einer Kombination von Werten als die andere hatte:

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

Kredit geht hier: http://asktom.Oracle.com/pls/apex/f?p=100:11::::P11_QUESTION_ID:1417403971710

3

Verwenden Sie ein Drittanbieter-Tool wie SQL Data Examiner , das Oracle-Datenbanken vergleicht und Unterschiede anzeigt.

1
SQLDev

Es wird nicht schnell sein und es wird eine Menge für Sie geben (es sei denn, Sie generieren die SQL aus user_tab_columns), aber ich verwende hier, wenn ich zwei Tabellen zeilenweise und spaltenweise miteinander vergleichen muss. Säule.

Die Abfrage gibt alle Zeilen zurück

  • Existiert in Tabelle1, aber nicht in Tabelle2
  • Existiert in Tabelle2, aber nicht in Tabelle1
  • Ist in beiden Tabellen vorhanden, hat jedoch mindestens eine Spalte mit einem anderen Wert

(gemeinsame identische Zeilen werden ausgeschlossen).

"PK" ist die Spalte (n), aus der sich Ihr Primärschlüssel zusammensetzt. "A" enthält A, wenn die aktuelle Zeile in Tabelle1 vorhanden ist. "B" enthält B, falls die aktuelle Zeile vorhanden ist existiert 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 Beispielcode hinzugefügt, um den in Kommentar beschriebenen Unterschied anzuzeigen. Immer wenn einer der Werte NULL enthält, ist das Ergebnis unterschiedlich.

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

Die Verwendung des minus-Operators funktionierte, aber auch die Ausführung dauerte länger, was nicht akzeptabel war. Ich habe eine ähnliche Anforderung an die Datenmigration und habe dafür den Operator NOT IN verwendet. Die geänderte Abfrage lautet: 

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

Diese Abfrage wurde schnell ausgeführt. Sie können auch eine beliebige Anzahl von Spalten in der Auswahlabfrage hinzufügen. Der einzige Haken ist, dass beide Tabellen genau dieselbe Tabellenstruktur haben sollten, damit diese ausgeführt werden kann.

0
AKS
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

Vollständige äußere Verknüpfung verwendet - Wird jedoch nicht angezeigt, wenn keine Übereinstimmung vorliegt.

SQL> desc aaa - es ist eine Tabelle Name Null? Art


A1 NUMMER B1 VARCHAR2 (10)

SQL> desc aaav -es a view Name Null? Art


A1 NUMMER B1 VARCHAR2 (10)

SQL> Wählen Sie a.column_name, b.column_name unter dba_tab_columns einen vollständigen äußeren Join aus. Dba_tab_columns b unter a.column_name = b.column_name wobei a.TABLE_NAME = 'AAA' und B.table_name = 'AAAV';

COLUMN_NAME COLUMN_NAME


A1 A1 B1 B1

0
Vasanth Raju