2010-01-29 7 views
4

구성된 열의 중복 항목 (여기 : city, zip)을 SQL에서 제거 할 수 있습니까? 그래서 만약 내가이 SQL을 가지고 :SQL을 통해 중복 항목을 삭제 하시겠습니까?

INSERT INTO foo (id, city, zip) VALUES (1, 'New York', '00000') 
INSERT INTO foo (id, city, zip) VALUES (2, 'New York', '00000') 

나는 SQL 문을 처음으로 나중에 제거 할 수 있습니까? 내 접근 방식이 작동하지 않습니다.

DELETE FROM foo (id, city, zip) 
     WHERE id IN 
      (SELECT id FROM foo GROUP BY id HAVING (COUNT(zip) > 1)) 
+2

하나만 제거하거나 하나만 남겨 두시겠습니까? 일치하는 항목이 3 개있는 속임수를 사용하는 즉시 문제가됩니다. – Lucero

+0

오직 하나만 있습니다. – codevour

답변

6

적응한 this article에서 적응했습니다. 이 두 가지 솔루션은 일반적이며 합리적인 SQL 구현에서 작동해야합니다.

DELETE T1 
FROM foo T1, foo T2 
WHERE (T1.city = T2.city AND foo1.zip=foo2.zip) -- Duplicate rows 
    AND T1.id > T2.id;       -- Delete the one with higher id 

단순하고 작은 중복 작은 테이블이나 테이블에 대해 잘 작동합니다 :

자리에서 중복을 제거합니다.

다른 테이블에 고유 한 기록을 복사

CREATE TABLE foo_temp LIKE(foo); 
INSERT INTO foo_temp (SELECT distinct city, zip) FORM foo; 
TRUNCATE TABLE foo; 

당신은 단순히 당신의 ID와 같은 순서를 가질 정도로 운이 좋다면 :

INSERT INTO foo SELECT * FROM foo_temp; 
DROP TABLE foo_temp; 

조금 더 복잡하지만 매우 효율적 중복이 많은 초대형 테이블. 이를 위해 (city, zip)에 대한 색인을 생성하면 쿼리 성능이 엄청나게 향상됩니다.

+1

"진행 중"- 편집 중에도이 작업을 기억해야합니다.;) – Lucero

+0

그래. 나는 다른 사람들이 동일한 아이디어로 경주에 그들의 시간을 낭비하는 것을 막는 일반적인 생각을 터뜨린다. –

1

다른 방언에는 다른 기능이 있기 때문에 어떤 SQL이 지원되는지는 명확하지 않습니다. 어떻게 내 마음에 오는 대신 HAVING의 내부 쿼리에서 zip에 순위를 사용하는 것입니다 만 순위 가진 사람> 1.

+0

SQL98이 가장 좋을 것입니다. – codevour

2
SQL Server 2005에서

이상을 포함한다 :

WITH q AS 
     (
     SELECT *, 
       ROW_NUMBER() OVER (PARTITION BY city, zip ORDER BY id) AS rn, 
       COUNT(*) OVER (PARTITION BY city, zip ORDER BY id) AS cnt 
     FROM mytable 
     ) 
DELETE 
FROM q 
WHERE rn = 1 
     AND cnt > 1 

는 첫 번째 행을 삭제하는 방법을 ,

WITH q AS 
     (
     SELECT *, ROW_NUMBER() OVER (PARTITION BY city, zip ORDER BY id) AS rn 
     FROM mytable 
     ) 
DELETE 
FROM q 
WHERE rn = 2 

처음 중복 삭제 (중복을 갖는)

WITH q AS 
     (
     SELECT *, ROW_NUMBER() OVER (PARTITION BY city, zip ORDER BY id) AS rn 
     FROM mytable 
     ) 
DELETE 
FROM q 
WHERE rn > 1 

모든 중복을 삭제하십시오.

+0

+1 - 내 의견에 의미가있는 내용이긴하지만 글을 쓸만큼 유창하지는 않습니다. – Lucero

1
DELETE FROM 
    cities 
WHERE 
    id 
NOT IN 
(
    SELECT id FROM 
    (
     -- Get the maximum id of any zip/city combination 
      -- This will work with both duped and non-duped rows 
     SELECT 
      MAX(id), 
      city, 
      zip 
     FROM 
      cities 
     GROUP BY 
      city, 
      zip 
    ) ids_only 
) 
0

oracle db에서 허용되는 대답이 작동하지 않았습니다. 이했던 :

DELETE FROM 
    mytable A 
WHERE 
    A.rowid > 
    ANY (
    SELECT 
     B.rowid 
    FROM 
     mytable B 
    WHERE 
     A.col1 = B.col1 
    AND 
     A.col2 = B.col2 
     ); 

을 (대신 ROWID의 모든 열 작동합니다.)

here 발견.

관련 문제