Database/SQL

Oracle 오라클 중복 데이터 제거, ROWID

리커니 2014. 5. 9.
반응형

 

Oracle 오라클 중복 데이터 제거, ROWID

이번 포스팅에서는 중복된 데이터가 있을때 

하나의 데이터만 남기고 삭제하는 방법에 대해서 포스팅 하겠습니다.

(중복된 데이터를 찾는 법은 아래의 Link를 참조하세요.)

 

Link : Oracle 중복 데이터 찾는 방법

 

중복 데이터가 존재할 때 하나의 값만 남기고 삭제하기 위해선

오라클 함수인 ROWID 를 사용하여 각 행에 ID 값을 SELECT 한 후

ID값이 MAX 인값만 남기고 나머지를 삭제 하면 됩니다.

 

(ROWID : 테이블에 있는 해당 로우를 찾기위해 오라클 DB내에서 사용되는 논리적인 정보, 컬럼이 unique 하지 않을때 유일 성을 부여할 수 있다.)

 

Link 와 같은 테이블을 사용해 예를 들어보겠습니다.

대한민국 행정동 코드가 있을 때 '동' 이 중복되는 데이터를 찾습니다.

이제 삭제할 대상의 ROWIDROWID의 MAX값을 SELECT 한 후

ROWID의 MAX 값보다 작은 ROWID를 구합니다.

 


[ROWID를 주기 전 결과]

 

SELECT T1.KIKB_DONG_NM

           , COUNT(*)

  FROM CM_KIK_B T1

 GROUP BY T1.KIKB_DONG_NM

 HAVING COUNT(*) > 1 ;

 

 


[ROWID를 준 결과]

 

SELECT T1.*

  FROM (

        SELECT S1.KIKB_DO_NM

    , S1.KIKB_DONG_NM

                   , COUNT(*) OVER(PARTITION BY S1.KIKB_DONG_NM) AS OVERLAP

                   , S1.ROWID AS RID

               , MAX(S1.ROWID) OVER (PARTITION BY S1.KIKB_DONG_NM) AS MAX_RID

          FROM CM_KIK_B S1

          ) T1

  WHERE T1.OVERLAP > 1 

    AND T1.RID < MAX_RID;

 

 


 

ROWID 가 MAX 인 값을 제외하고 조회 된 것을 볼 수 있습니다.

ROW_NUMBER 를 사용하여도 같은 결과를 가져올 수 있습니다.

 


[ROW_NUMBER() 사용]

 

SELECT T1.*

  FROM (

             SELECT S1.KIKB_DO_NM

         , S1.KIKB_DONG_NM

                       , COUNT(*) OVER(PARTITION BY S1.KIKB_DONG_NM) AS OVERLAP

                       , S1.ROWID AS RID

                  , ROW_NUMBER() OVER (PARTITION BY S1.KIKB_DONG_NM 

                                                         ORDER BY S1.ROWID DESC) AS RN

               FROM CM_KIK_B S1

          ) T1

 WHERE T1.RN > 1

 

 


 

이제 SELECT 한 이 결과 값들만 삭제하면 되겠죠?

이제 위의 SELECT 문의 RID 만 SELECT 해 같은 것이 있으면 삭제 하겠습니다.

여기서는 IN 을 사용합니다.

(IN의 사용법은 아래의 Link를 참조하세요.)

 

Link : Subquery 서브쿼리사용법, ALL, ANY, IN, EXISTS

 


DELETE   -- DELETE 전에 SELECT 먼저 해봅니다. (SELECT T1.*)

  FROM CM_KIK_B T1

 WHERE T1.ROWID IN (

                 SELECT S1.RID

                                  FROM (

                                            SELECT S1.ROWID AS RID

                                                       , ROW_NUMBER() OVER (PARTITION BY S1.KIKB_DONG_NM 

                                                                                                 ORDER BY S1.ROWID DESC) AS RN

                                               FROM CM_KIK_B S1

                                            ) S1

                                WHERE S1.RN > 1

                                ) ; 

 


 

이제 전국에서 '동' 은 하나씩만 존재할 것입니다.

 

* DELETE문이나 UPDATE 문 사용시에는 우선 SELECT 하여 값이 맞는 지 확인 후에 실행하는 습관을 드리는 것이 좋습니다.

 

반응형

댓글

💲 추천 글