복붙노트

[SQL] PostgreSQL의에서 중복 레코드 삭제

SQL

PostgreSQL의에서 중복 레코드 삭제

나는 아무런 키 / 제약이 없으며, 정확히 같은 값을 가진 여러 행이있는 PostgreSQL의 8.3.8 데이터베이스에서 테이블을 가지고있다.

나는 모든 중복을 제거하고 각 행의 1 사본을 보관하고 싶습니다.

(각 별개의 "키"에 대한 하나 명의 엔트리가 존재한다, 즉) 중복을 식별하는데 이용 될 수있다 특히, 하나의 열 (명명 된 "키")가있다.

이걸 어떻게 할 수 있습니까? (이상적으로 하나의 SQL 명령) 속도가이 경우에 문제가되지 않습니다 (몇 행이).

해결법

  1. ==============================

    1.

    DELETE FROM dupes a
    WHERE a.ctid <> (SELECT min(b.ctid)
                     FROM   dupes b
                     WHERE  a.key = b.key);
    
  2. ==============================

    2.더 빠른 솔루션입니다

    더 빠른 솔루션입니다

    DELETE FROM dups a USING (
          SELECT MIN(ctid) as ctid, key
            FROM dups 
            GROUP BY key HAVING COUNT(*) > 1
          ) b
          WHERE a.key = b.key 
          AND a.ctid <> b.ctid
    
  3. ==============================

    3.이것은 빠르고 간결 :

    이것은 빠르고 간결 :

    DELETE FROM dupes T1
        USING   dupes T2
    WHERE   T1.ctid < T2.ctid  -- delete the older versions
        AND T1.key  = T2.key;  -- add more columns if needed
    

    자세한 정보가 포함되어 고유 식별자없이 중복 행을 삭제하는 방법에 내 대답은 참조하십시오.

  4. ==============================

    4.나는이 시도 :

    나는이 시도 :

    DELETE FROM tablename
    WHERE id IN (SELECT id
                  FROM (SELECT id,
                                 ROW_NUMBER() OVER (partition BY column1, column2, column3 ORDER BY id) AS rnum
                         FROM tablename) t
                  WHERE t.rnum > 1);
    

    포스트 그레스 위키에 의해 제공 :

    https://wiki.postgresql.org/wiki/Deleting_duplicates

  5. ==============================

    5.난 내 자신의 버전을 작성했다. @a_horse_with_no_name 쓴 버전은 내 테이블 (21M 행)에 너무 느린 방법입니다. 그리고 @rapimo 단순히 DUPS 삭제되지 않습니다.

    난 내 자신의 버전을 작성했다. @a_horse_with_no_name 쓴 버전은 내 테이블 (21M 행)에 너무 느린 방법입니다. 그리고 @rapimo 단순히 DUPS 삭제되지 않습니다.

    여기에 내가 PostgreSQL의 9.5에서 사용하는 것입니다

    DELETE FROM your_table
    WHERE ctid IN (
      SELECT unnest(array_remove(all_ctids, actid))
      FROM (
             SELECT
               min(b.ctid)     AS actid,
               array_agg(ctid) AS all_ctids
             FROM your_table b
             GROUP BY key1, key2, key3, key4
             HAVING count(*) > 1) c);
    
  6. ==============================

    6.나는 임시 테이블을 사용합니다 :

    나는 임시 테이블을 사용합니다 :

    create table tab_temp as
    select distinct f1, f2, f3, fn
      from tab;
    

    그런 다음, 삭제 탭 탭에 이름 바꾸기 tab_temp.

  7. ==============================

    7.이것은 나를 위해 잘 작동. 나는 중복 값이 ​​포함 된 테이블, 용어를했다. 중복 행 모두와 함께 임시 테이블을 채우는 쿼리를 실행했습니다. 그럼 난 임시 테이블에서 그 식별자와 삭제 문을 달렸다. 값이 중복 포함 된 칼럼이다.

    이것은 나를 위해 잘 작동. 나는 중복 값이 ​​포함 된 테이블, 용어를했다. 중복 행 모두와 함께 임시 테이블을 채우는 쿼리를 실행했습니다. 그럼 난 임시 테이블에서 그 식별자와 삭제 문을 달렸다. 값이 중복 포함 된 칼럼이다.

            CREATE TEMP TABLE dupids AS
            select id from (
                        select value, id, row_number() 
    over (partition by value order by value) 
        as rownum from terms
                      ) tmp
                      where rownum >= 2;
    
    delete from [table] where id in (select id from dupids)
    
  8. ==============================

    8.열에 의한 모든 고유 ID를 찾아 독특한 목록에없는 다른 ID를 제거하는 또 다른 방법은 (당신이 당신의 테이블에 ID와 같은 고유 필드가있는 경우에만 작동)

    열에 의한 모든 고유 ID를 찾아 독특한 목록에없는 다른 ID를 제거하는 또 다른 방법은 (당신이 당신의 테이블에 ID와 같은 고유 필드가있는 경우에만 작동)

    DELETE
    FROM users
    WHERE users.id NOT IN (SELECT DISTINCT ON (username, email) id FROM users);
    
  9. from https://stackoverflow.com/questions/6583916/delete-duplicate-records-in-postgresql by cc-by-sa and MIT license