programing

oracle diff: 두 테이블을 비교하는 방법

lastmoon 2023. 3. 23. 23:04
반응형

oracle diff: 두 테이블을 비교하는 방법

레이아웃은 같지만 데이터가 다를 수 있는 t1과 t2의 두 표가 있다고 가정합니다.

이 두 테이블을 구분하는 가장 좋은 방법은 무엇입니까?

이것을 시험해 보세요.

(select * from T1 minus select * from T2) -- all rows that are in T1 but not in T2
union all
(select * from T2 minus select * from T1)  -- all rows that are in T2 but not in T1
;

외부 툴은 없습니다.퍼포먼스 문제는 없습니다.union all.

set 조작을 사용해 볼 수 있습니다.MINUS그리고.INTERSECT

자세한 내용은 여기를 참조해 주세요.
O'Reilly - Oracle SQL 마스터링 - 7장 - Set Operations

AQT 등의 도구를 사용하여 테이블 간에 차이를 만들 수 있습니다.

또 다른 접근법은 테이블을 텍스트파일에 덤프하고 WinMerge와 같은 다른 도구를 사용하는 것입니다.이 방법을 사용하면 먼저 복잡한 SQL을 사용하여 테이블을 동일한 레이아웃으로 변환할 수 있습니다.

신속한 솔루션:

SELECT * FROM TABLE1
MINUS
SELECT * FROM TABLE2

기록이 없으면...

이러한 질문에는, 다양한 해석 방법이나 다양한 어프로치가 있기 때문에, 무엇을 찾고 있는지를 명확하게 할 필요가 있다고 생각합니다.당신의 질문이 타당하지 않다면 어떤 접근법은 너무 큰 문제가 될 것이다.

가장 간단한 수준에는 "테이블 데이터가 정확히 동일한가?"가 있습니다. 이 경우 더 복잡한 항목으로 넘어가기 전에 간단한 카운트 비교로 응답할 수 있습니다.

척도의 다른 쪽 끝에는 "다른 표에 동등한 행이 없는 각 테이블의 행을 표시해 주세요" 또는 "같은 식별 키를 가지지만 다른 데이터 값을 가진 행의 행을 표시해 주세요"가 있습니다.

실제로 표 A와 표 B를 동기화하는 경우는 MERGE 명령어를 사용하면 비교적 간단하게 동기화할 수 있습니다.

Oracle SQL 개발자를 사용하여 테이블을 CSV 형식으로 내보낸 후 WinMerge를 사용하여 비교했습니다.

dbForge Data Compare for Oracle은 데이터 비교 및 동기화를 위한 ** 무료 GUI 도구입니다.이 도구는 모든 데이터베이스 또는 부분적으로 이러한 작업을 수행할 수 있습니다.

alt 텍스트

select * from table1 where table1.col1 in (select table2.col1 from table2)

가정하다col1프라이머리 키열로, 모든 행이 표시됩니다.table1각각에 대해서table2열 1

select * from table1 where table1.col1 not in (select table2.col1 from table2)

도움이 되었으면 좋겠다

여기에 제시된 다른 답변과 더불어 유사하지만 다른 구조를 가질 수 있는 표와 표 구조의 차이를 확인하는 경우 다음과 같은 여러 가지 방법을 사용할 수 있습니다.

번째 - Oracle SQL Developer를 사용하는 경우 두 테이블에서 설명을 실행하여 비교할 수 있습니다.

descr TABLE_NAME1
descr TABLE_NAME2

번째 - 첫 번째 솔루션은 열이 많은 큰 표에는 적합하지 않을 수 있습니다.여러 테이블에서 언급한 것처럼 두 테이블 간의 데이터 차이만 보려면 SQL Minus 연산자를 사용해야 합니다.

번째 - 오라클 SQL Developer를 사용하는 경우 서로 다른 스키마를 사용하여 두 테이블의 테이블 구조를 비교하려면 다음을 수행할 수 있습니다.

  1. "도구"를 선택합니다.
  2. "데이터베이스 차이"를 선택합니다.
  3. "소스 연결"을 선택합니다.
  4. "대상 연결"을 선택합니다.
  5. 비교할 "표준 개체 유형"을 선택하십시오.
  6. "테이블 이름" 입력
  7. "완료"에 도달할 때까지 "다음"을 클릭하십시오.
  8. [완료]를 클릭합니다.
  9. 메모: 순서 3과 4에서는 비교할 오브젝트가 존재하는 스키마를 선택합니다.

번째 - 비교할 테이블이 더 많고 같은 스키마 내에 있으며 두 개 이상의 테이블을 비교할 필요가 없으며 DESCR 명령을 사용하여 시각적으로 비교할 필요가 없는 경우 다음을 사용하여 테이블 구조의 차이를 비교할 수 있습니다.

select 
     a.column_name    || ' | ' || b.column_name, 
     a.data_type      || ' | ' || b.data_type, 
     a.data_length    || ' | ' || b.data_length, 
     a.data_scale     || ' | ' || b.data_scale, 
     a.data_precision || ' | ' || b.data_precision
from 
     user_tab_columns a,
     user_tab_columns b
where 
     a.table_name = 'TABLE_NAME1' 
and  b.table_name = 'TABLE_NAME2'
and  ( 
       a.data_type      <> b.data_type     or 
       a.data_length    <> b.data_length   or 
       a.data_scale     <> b.data_scale    or 
       a.data_precision <> b.data_precision
     )
and a.column_name = b.column_name;

시험:

select distinct T1.id
  from TABLE1 T1
 where not exists (select distinct T2.id
                     from TABLE2 T2
                    where T2.id = T1.id)

sql oracle 11g+ 탑재

이것을 시험해 보세요.

세션 세트 "_session_set_to_session"= true를 변경합니다.

다른 대안은 SQL 쿼리를 수동으로 다시 쓰는 것입니다.[마이너스 연산자를 NOT IN 서브 쿼리로 대체] 실행 시간이 약 30% 단축되었음을 증명합니다.

 select * 
   from A 
    where (col1,col2,?) not in 
   (select col1,col2,? from B) 
   union all 
   select * from B 
  where (col1,col2,?) not in 
  (select col1,col2,? from A); 

포스트클릭에서 참조했습니다.

아래는 분산된 테이블이 중복된 행을 가질 수 있다는 점을 고려한 해결 방법입니다.승인된 답변은 이 점을 고려하지 않으므로 중복될 경우 잘못된 결과를 얻을 수 있습니다.중복된 행은 row_number()를 사용하여 번호를 매긴 후 번호가 매겨진 행을 비교하여 처리하고 있습니다.

-- TEST TABLES
create table t1 (col_num number,col_date date,col_varchar varchar2(400));
create table t2 (col_num number,col_date date,col_varchar varchar2(400));  

-- TEST DATA
insert into t1 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am in both');
insert into t2 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am in both');

insert into t1 values (null,null,'I am in both with nulls');
insert into t2 values (null,null,'I am in both with nulls');

insert into t1 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am in T1 only');
insert into t2 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am in T2 only');

insert into t1 values (null,null,'I am in T1 only with nulls');
insert into t2 values (null,null,'I am in T2 only with nulls');

insert into t1 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T1 but not in T2');
insert into t1 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T1 but not in T2');

insert into t2 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T2 but not in T1');
insert into t2 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T2 but not in T1');

insert into t1 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T1 and once in T2');
insert into t1 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T1 and once in T2');
insert into t2 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T1 and once in T2');

insert into t2 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T2 and once in T1');
insert into t2 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T2 and once in T1');
insert into t1 values (1,TO_DATE ('01.JAN.3000 00:00:00', 'DD.MON.YYYY HH24:MI:SS'),'I am twice in T2 and once in T1');

-- THE DIFF
-- All columns need to be named in the partition by clause, it is not possible to just say 'partition by *'
-- The column used in the order by clause does not matter in terms of functionality 
(
    select 'In T1 but not in T2' diff,s.* from (
        select row_number() over (partition by col_num,col_date,col_varchar order by col_num) rn,t.* from t1 t
        minus
        select row_number() over (partition by col_num,col_date,col_varchar order by col_num) rn,t.* from t2 t
    ) s
) union all (
    select 'In T2 but not in T1' diff,s.* from (
        select row_number() over (partition by col_num,col_date,col_varchar order by col_num) rn,t.* from t2 t
        minus
        select row_number() over (partition by col_num,col_date,col_varchar order by col_num) rn,t.* from t1 t
    ) s
);

언급URL : https://stackoverflow.com/questions/688537/oracle-diff-how-to-compare-two-tables

반응형