#title 중복행제거하기(2005이상) [[TableOfContents]] ==== 샘플 ==== 커뮤니티에 보면 가끔 중복행을 제거하고 싶다는 질문들이 올라오고는 한다. 예를 들어 다음과 같은 경우다. {{{ --샘플 테이블 생성 CREATE TABLE MEMBER( IDX int identity(1,1) , NAME Char(20) ) GO --샘플 데이터 입력 INSERT INTO MEMBER VALUES('A') INSERT INTO MEMBER VALUES('A') INSERT INTO MEMBER VALUES('B') INSERT INTO MEMBER VALUES('B') INSERT INTO MEMBER VALUES('B') INSERT INTO MEMBER VALUES('B') INSERT INTO MEMBER VALUES('C') INSERT INTO MEMBER VALUES('C') GO }}} ==== 2000 버전에서의 처리 방법 ==== 근본적인 해결 방법이 아니다. 중복이 발생하지 않는 환경을 만드는 것이 중요하다. {{{ --2000이하 버전 DELETE FROM MEMBER WHERE IDX IN ( SELECT A.IDX as IDX FROM MEMBER A INNER JOIN ( SELECT MAX(IDX) AS IDX , NAME AS NAME , COUNT(*) AS CNT FROM MEMBER GROUP BY NAME HAVING COUNT(*) >1) B ON A.NAME = B.NAME AND A.IDX!=B.IDX ) }}} ==== 2005 이상 버전에서의 처리 방법 ==== {{{ --2005이상 버전(위 솔루션보다 훨씬 적은 비용으로 처리할 수 있다) DELETE A FROM ( SELECT IDX , NAME , ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY IDX) NUM FROM MEMBER ) A WHERE NUM <> 1 }}} ==== 두 SQL문의 처리 비용 비교 ==== attachment:cost.jpg 데이터가 얼마 되지 않아 비용차를 크게 못 느낄 수도 있지만, 대용량에서는 많은 성능차이가 있다. ==== 근본적인 원인 ==== 중복행의 제거는 Unique해야 할 데이터가 Unique하지 않아서 생긴 문제다. 애초에 중복이 발생한 원인을 찾아야 한다. DB설계의 입장에서 본다면 Unique 제약조건을 걸지 않아서 생긴 문제이고, DB설계 이전에 본다면 전체 시스템이 현실을 제대로 반영하지 못해서 생긴 문제다. 현실을 제대로 반영하는 것은 설계의 기본 중에 기본이다.