Contents

[-]
1 샘플
2 2000 버전에서의 처리 방법
3 2005 이상 버전에서의 처리 방법
4 두 SQL문의 처리 비용 비교
5 근본적인 원인


1 샘플 #

커뮤니티에 보면 가끔 중복행을 제거하고 싶다는 질문들이 올라오고는 한다. 예를 들어 다음과 같은 경우다.
--샘플 테이블 생성
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

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

3 2005 이상 버전에서의 처리 방법 #

--2005이상 버전(위 솔루션보다 훨씬 적은 비용으로 처리할 수 있다)
DELETE A
FROM 
(
	SELECT 
		IDX
	,	NAME
	,	ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY IDX) NUM
	FROM MEMBER
) A
WHERE NUM <> 1

4 두 SQL문의 처리 비용 비교 #

cost.jpg

데이터가 얼마 되지 않아 비용차를 크게 못 느낄 수도 있지만, 대용량에서는 많은 성능차이가 있다.

5 근본적인 원인 #

중복행의 제거는 Unique해야 할 데이터가 Unique하지 않아서 생긴 문제다. 애초에 중복이 발생한 원인을 찾아야 한다. DB설계의 입장에서 본다면 Unique 제약조건을 걸지 않아서 생긴 문제이고, DB설계 이전에 본다면 전체 시스템이 현실을 제대로 반영하지 못해서 생긴 문제다. 현실을 제대로 반영하는 것은 설계의 기본 중에 기본이다.
Retrieved from http://databaser.net/moniwiki/wiki.php/중복행제거하기(2005이상)
last modified 2018-04-13 23:12:54