2011-05-07 8 views
2

테이블에 고유 키 ID 키가 있지만 중복 값이있는 열이 있습니까?테이블에서 중복 행을 삭제하십시오.

중복 기록 : 중복없이

id | name | surname | 
1 | test | one  | 
2 | test | two  | 
3 | test3 | three | 
4 | test7 | four | 
5 | test | five | 
6 | test11 | eleven | 

: 어떻게이 같은 그 중 하나 유지하면서, 그 제거합니까

id | name | surname | 
1 | test | one  | 
3 | test3 | three | 
4 | test7 | four | 
6 | test11 | eleven | 

내가이 검색 좀했습니다를하지만하지 보인다 작업 할 :

DELETE ct1 
FROM mytable ct1 
     , mytable ct2 
WHERE ct1.name = ct2.name 
     AND ct1.id < ct2.id 

ERROR: syntax error at or near "ct1" 
LINE 1: DELETE ct1 
       ^

********** Error ********** 

나는 postgres 데이터베이스를 사용하고 있습니다.

+0

데이터를 정리 한 후에는 "이름"에 UNIQUE 제약 조건을 지정해야 할 수 있습니다. –

답변

3

당신이 실행 여러 번을 시도 할 수 있습니다 :

여러 번 당신이 name 열에있는 반복의 최대 수를 동일
delete from mytable where id in (
    select max(id) 
     from mytable 
    group by name 
    having count(1) > 1 
); 

. 단지 당신이 필요로하는 모든을 삭제해야이 쿼리를 한 번 실행

delete from mytable where id in (
    select id from mytable 
    except 
    (
    select min(id) 
     from mytable 
    group by name 
    having count(1) > 1 
    union all 
    select min(id) 
     from mytable 
    group by name 
    having count(1) = 1 
    ) 
); 

:

그렇지 않으면, 당신이 더 복잡한 쿼리를 시도 할 수 있습니다. 그래도 사용해 본적이 없다 ...

+0

복잡한 쿼리가 작동했습니다. 시도하지 않고도 훌륭하게 작동했습니다. –

+2

도움이 되니 기쁩니다. 이와 같은 복잡한 그룹화를 위해서는'Rank' @Dalen이 다른 대답으로 제안하는 것과 같은'창 함수'를 배우는 것이 좋습니다. 그들은 배우는 가치가 있습니다. –

3

Rank을 사용하면, 실제로 나는 PostgreSQL에 좋지 않기 때문에 구문에 대해 완전히 확신하지 못한다. 이것은 어쨌든 힌트 일 뿐이다 (아무도 수정하지 않을 것이다).

DELETE FROM mytable 
WHERE id NOT IN 
(
    SELECT x.id FROM 
    (
     SELECT id, RANK() OVER (PARTITION BY name ORDER BY id ASC) AS r 
     FROM mytable 
    ) x 
    WHERE x.r = 1 
) 
관련 문제