복붙노트

[SQL] 테이블을 중복 제거하는 가장 좋은 방법은 무엇입니까?

SQL

테이블을 중복 제거하는 가장 좋은 방법은 무엇입니까?

나는이 솔루션의 몇 가지를 본 적이 있지만 나는 최고의 가장 효율적인 방법은 테이블을 해제 속는 것입니다 무엇인지 궁금하네요. 당신은 당신의 점을 설명하기 위해 코드 (SQL 등)을 사용할 수 있지만, 난 그냥 기본 알고리즘을 찾고 있어요. 이미 SO에 이것에 대해 질문이있을 것입니다 가정,하지만 난 그렇게이 이미 존재하는 경우 단지 나에게 머리를 포기, 하나를 찾을 수 없습니다.

(그냥 명확히하기 - 내가 자동 증분 PK를 가지고 있으며 테이블의 중복을 제거하기 말하는 겁니다 모든하지만 PK 필드에 중복 일부 행이 있습니다.)

해결법

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

    1.DISTINCT SELECT foo는 FROM <모든 열하지만 여기에 PK 삽입>. 다음, 해당 쿼리를 (구문이 RDBMS에 따라 다릅니다 만이 일반적이다는 SELECT ... INTO 또는 사용 가능한 패턴으로 테이블 만들기)를 사용하여 임시 테이블을 만들기 이전 테이블을 날려과에 임시 테이블의 뒷면에서 데이터 펌프.

    DISTINCT SELECT foo는 FROM <모든 열하지만 여기에 PK 삽입>. 다음, 해당 쿼리를 (구문이 RDBMS에 따라 다릅니다 만이 일반적이다는 SELECT ... INTO 또는 사용 가능한 패턴으로 테이블 만들기)를 사용하여 임시 테이블을 만들기 이전 테이블을 날려과에 임시 테이블의 뒷면에서 데이터 펌프.

  2. ==============================

    2.분석 함수의 ROW_NUMBER 사용 :

    분석 함수의 ROW_NUMBER 사용 :

    WITH CTE (col1, col2, dupcnt)
    AS
    (
    SELECT col1, col2,
    ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col1) AS dupcnt
    FROM Youtable
    )
    DELETE
    FROM CTE
    WHERE dupcnt > 1
    GO                                                                 
    
  3. ==============================

    3.향후 참조를 위해 여기에 실제 코드를 추가

    향후 참조를 위해 여기에 실제 코드를 추가

    따라서, 3 단계, 따라서 3 SQL 문이 있습니다

    1 단계 : 임시 테이블에 비 중복 (고유 한 튜플) 이동

    CREATE TABLE new_table as
    SELECT * FROM old_table WHERE 1 GROUP BY [column to remove duplicates by];
    

    2 단계 : 기존 테이블을 삭제 (또는 이름을 변경) 우리는 더 이상 그렇게 드롭, 모든 중복 항목이 테이블을 필요가 없습니다!

    DROP TABLE old_table;
    

    3 단계 : OLD_TABLE의 이름으로 NEW_TABLE 이름을 변경

    RENAME TABLE new_table TO old_table;
    

    그리고 물론, 중복 삽입을 중지하기 위해 버그 코드를 수정하는 것을 잊지 마세요!

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

    4.중복 기능은 거의 간단하다. 기록은 종종 dedupped 될 때문에의 약간 다른 값을 가지고하면 필드의 일부입니다. 따라서 문제가 될 수 있습니다 유지하는 기록을 선택합니다. 또한, DUPS는 종종 사람들의 기록이며, 두 개의 존 스미스의 두 사람 또는 중복 한 사람이 있는지 확인하기 어렵다. 그래서 DUP 방법의 차이와 자식 레코드를 처리하는 방법을 구성하는 것에 정의 (자세한 전체 프로젝트의 50 %) 많은 시간을 보낸다.

    중복 기능은 거의 간단하다. 기록은 종종 dedupped 될 때문에의 약간 다른 값을 가지고하면 필드의 일부입니다. 따라서 문제가 될 수 있습니다 유지하는 기록을 선택합니다. 또한, DUPS는 종종 사람들의 기록이며, 두 개의 존 스미스의 두 사람 또는 중복 한 사람이 있는지 확인하기 어렵다. 그래서 DUP 방법의 차이와 자식 레코드를 처리하는 방법을 구성하는 것에 정의 (자세한 전체 프로젝트의 50 %) 많은 시간을 보낸다.

    당신은 어떻게 올바른 값 인 알 수 있습니까? 또한 dedupping 당신이 어떤을 orphaning 모든 자식 레코드를 처리해야합니다. 당신은 당신이 갑자기 고유 인덱스 또는 제약 조건 중 하나를 위반하고 자식 레코드 ID를 변경하여 그것을 발견 할 때 어떤 일이 발생 -이 결국 그것을 처리하고 프로세스 요구를 발생합니다. 당신은 철저한 응용 프로그램을 모든 제약 조건을 적용 어리석게 선택한 경우, 당신도 제약을 위반 알 수 없습니다. 당신이 DEDUP하기 만 개 기록이있을 때, 당신은 한 번에 DEDUP 하나의 응용 프로그램을 통해 갈 수 없습니다. 제약 조건은 데이터베이스에없는 경우, 데이터 무결성을 유지 행운의 많은 당신은 DEDUP 때.

    또 다른 합병증은 DUPS 항상 이름이나 주소를 정확히 일치하지 않는 것입니다. 예를 들어 조안 마틴이라는 이름의 영업 담당자는 영업 담당자 이름이 동일한 주소와 이메일이 특히 조안 마틴 존스의 DUP 수 있습니다. 또는 당신은 이름에서 존이나 조니있을 수 있습니다. 또는 하나 개의 레코드를 제외하고 같은 거리 주소는 ST를 abbreveiated. 하나는 거리를 밖으로 철자. SQL 서버에서 당신은 또한 가까운 일치를 식별하기 위해 SSIS 퍼지 그룹화를 사용할 수 있습니다. 이들은 종종 그들이 처음부터 DUPS로에 넣어있어 이유를 정확히 일치한다되지 않은 사실과 같은 가장 일반적인 DUPS 있습니다.

    dedupping 일부 유형의 경우, dedupping을하고있는 사람이 특정 분야에 사용할 두 개의 값을 선택할 수 있도록하는 것이, 사용자 인터페이스를해야 할 수도 있습니다. 이 dedupped되고있는 사람이 두 개 이상의 역할에있는 경우 특히 그렇습니다. 그것은 특정 역할에 대한 데이터는 일반적으로 더 나은 다른 역할에 대한 데이터보다이라고 할 수있다. 아니면 사용자 만이 올바른 값 인 확실히 알 수 또는 그들이 진정으로 DUPS 또는 동일한 이름을 가진 단순히 이명 여부를 알아 접촉 사람들에게해야 할 수도 수 있습니다.

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

    5.당신이 문에 의해 그룹으로 당신의 속는 기준을 얻을 수 있으며, 테이블 고유성에 대한 ID의 ID 열이있는 경우 여기에 방법 I 사용이다 :

    당신이 문에 의해 그룹으로 당신의 속는 기준을 얻을 수 있으며, 테이블 고유성에 대한 ID의 ID 열이있는 경우 여기에 방법 I 사용이다 :

    delete t
    from tablename t
    inner join  
    (
        select date_time, min(id) as min_id
        from tablename
        group by date_time
        having count(*) > 1
    ) t2 on t.date_time = t2.date_time
    where t.id > t2.min_id
    

    당신은 확실히 그들 모두에 가입 한 개 이상의 열 메이크업이있는 경우이 예에서 DATE_TIME는 그룹화 기준입니다.

  6. ==============================

    6.나는 DShook에서 하나를 복용하고 당신이 가장 높은 날짜 만 기록을 유지하는 것 중복 제거 예제를 제공하고 있습니다.

    나는 DShook에서 하나를 복용하고 당신이 가장 높은 날짜 만 기록을 유지하는 것 중복 제거 예제를 제공하고 있습니다.

    이 예에서는 내가 같은 APP_ID로 3 개 기록을 모두 가지고 있고, 나는 단지 가장 높은 날짜와 함께 일을 계속하고 싶은 말은 :

    DELETE t
    FROM @USER_OUTBOX_APPS t
    INNER JOIN  
    (
        SELECT 
             app_id
            ,max(processed_date) as max_processed_date
        FROM @USER_OUTBOX_APPS
        GROUP BY app_id
        HAVING count(*) > 1
    ) t2 on 
        t.app_id = t2.app_id
    WHERE 
        t.processed_date < t2.max_processed_date
    
  7. ==============================

    7.신속하고 더러운 방법을 선호하는 분들을 위해, 그냥 같이과 같이 고유 한 레코드를 정의하고 그 열이 고유 인덱스를 만들 모든 열을 나열합니다 :

    신속하고 더러운 방법을 선호하는 분들을 위해, 그냥 같이과 같이 고유 한 레코드를 정의하고 그 열이 고유 인덱스를 만들 모든 열을 나열합니다 :

    ALTER는 UNIQUE (1 열, 2 열, 3 열) 표 TABLE_NAME에 ADD를 무시

    당신은 고유 인덱스 afterwords을 놓을 수 있습니다.

  8. ==============================

    8.unkeyed_table FROM XY SELECT SQL의 경우, INSERT를 사용할 수 있습니다 테이블에 무시;

    unkeyed_table FROM XY SELECT SQL의 경우, INSERT를 사용할 수 있습니다 테이블에 무시;

    키가 반복 될 수에 - 수 - 주 알고리즘의 경우, 해당 가정 할 수 있다면,하지만하려면 - 수 - 기본 키는 고유의 해시 만에하는 - 수 - 기본 키보다, 행의 내용을 확인하고 반복 확인 .

  9. ==============================

    9.나는이 그냥 아이디를 제외한 모든 열을 기준으로 그룹화하고 각 그룹에서 하나 개의 행을 선택하는 더 아무 것도 필요하지한다고 생각 - 단순화를 위해 단지 첫 번째 행을,하지만 당신은 아이디에 대한 추가적인 제약이 외에이 문제가 실제로하지 않습니다.

    나는이 그냥 아이디를 제외한 모든 열을 기준으로 그룹화하고 각 그룹에서 하나 개의 행을 선택하는 더 아무 것도 필요하지한다고 생각 - 단순화를 위해 단지 첫 번째 행을,하지만 당신은 아이디에 대한 추가적인 제약이 외에이 문제가 실제로하지 않습니다.

    또는 다른 방법으로 주위는 모든 행이 모든 그룹에서 하나 하나를 받아 삭제 ... 행을 제거하는.

  10. ==============================

    10.당신은 (? 당신이 임시 스테이징 영역에 테이블을 이동할 수 있습니다, 당신은 새로운 열을 추가 할 수없는 경우 나) 새로운 컬럼에 보관합니다 (PK 제외) 각 행에 대해 해시를 생성하고 다른 모든 찾을 수 같은 해시와 행. 물론, 당신은 당신의 해쉬 함수는 다른 행에 대해 동일한 코드를 생성하지 않도록 할 수 있어야 할 것입니다.

    당신은 (? 당신이 임시 스테이징 영역에 테이블을 이동할 수 있습니다, 당신은 새로운 열을 추가 할 수없는 경우 나) 새로운 컬럼에 보관합니다 (PK 제외) 각 행에 대해 해시를 생성하고 다른 모든 찾을 수 같은 해시와 행. 물론, 당신은 당신의 해쉬 함수는 다른 행에 대해 동일한 코드를 생성하지 않도록 할 수 있어야 할 것입니다.

    두 행이 중복 된 경우, 당신이 제거하는 문제는 무엇입니까? 그것은 다른 데이터가 중복의 양에 의존하는 것이 가능합니까? 그렇다면, 당신은 몇 단계를 거쳐야합니다 :

    이는 기존 데이터 모델에 따라 쉽게 또는 복잡한 수 있습니다.

    유지 보수 및 재 설계 프로젝트 등이 모든 시나리오 소리. 그렇다면, 행운을 빕니다!

  11. ==============================

    11.이 C1에서 중복 값을 중복 제거 할 수 있습니다 :

    이 C1에서 중복 값을 중복 제거 할 수 있습니다 :

    select * from foo
    minus
    select f1.* from foo f1, foo f2
    where f1.c1 = f2.c1 and f1.c2 > f2.c2
    
  12. ==============================

    12.여기에 내가 현실에서,로 실행했습니다 하나입니다.

    여기에 내가 현실에서,로 실행했습니다 하나입니다.

    당신이 사용자에 대한 외부 / 타사 로그인의 테이블을 가지고, 당신은 공급자 / 공급 업체 키 값을 중복 제거에 두 명의 사용자를 병합 가고 싶어하고 가정합니다.

        ;WITH Logins AS
        (
            SELECT [LoginId],[UserId],[Provider],[ProviderKey]
            FROM [dbo].[UserLogin] 
            WHERE [UserId]=@FromUserID -- is the user we're deleting
                  OR [UserId]=@ToUserID -- is the user we're moving data to
        ), Ranked AS 
        (
            SELECT Logins.*
                , [Picker]=ROW_NUMBER() OVER (
                           PARTITION BY [Provider],[ProviderKey]
                           ORDER BY CASE WHEN [UserId]=@FromUserID THEN 1 ELSE 0 END)
            FROM Logins
        )
        MERGE Logins AS T
        USING Ranked AS S
        ON S.[LoginId]=T.[LoginID]
        WHEN MATCHED AND S.[Picker]>1 -- duplicate Provider/ProviderKey
                     AND T.[UserID]=@FromUserID -- safety check 
        THEN DELETE
        WHEN MATCHED AND S.[Picker]=1 -- the only or best one
                     AND T.[UserID]=@FromUserID
        THEN UPDATE SET T.[UserID]=@ToUserID
        OUTPUT $action, DELETED.*, INSERTED.*;
    
  13. ==============================

    13.이 방법이 작동하지만, PK로 명시 ID없이 다음 문제가 될 수 삭제 된 행을 결정하는 것입니다. 속는 가장 간단한 것 같다 않고 임시 테이블에 밖으로 바운스는 원본과 재 삽입에서 삭제합니다.

    이 방법이 작동하지만, PK로 명시 ID없이 다음 문제가 될 수 삭제 된 행을 결정하는 것입니다. 속는 가장 간단한 것 같다 않고 임시 테이블에 밖으로 바운스는 원본과 재 삽입에서 삭제합니다.

  14. ==============================

    14.을 중복 / 중복 제거 / 삭제 복제를 들어 / 무게뿐만 아니라 반복 행 / 데이터베이스 / 제거 중복 데이터베이스 레코드를 제거하는 여러 가지 방법이 있습니다.

    을 중복 / 중복 제거 / 삭제 복제를 들어 / 무게뿐만 아니라 반복 행 / 데이터베이스 / 제거 중복 데이터베이스 레코드를 제거하는 여러 가지 방법이 있습니다.

    그런 다음 TABLE_NAME_DEDUP는 중복 제거 된 테이블입니다.

    예를 들어,

    create table test (t1 varchar(5), t2 varchar(5));
    insert into test  values ('12345', 'ssdlh');
    insert into test  values ('12345', 'ssdlh');
    create table test_dedup as
    select * from test 
    group by t1, t2;
    -----optional
    --remove original table and rename dedup table to previous table
    --this is not recommend in dev or qa. DROP table test; Alter table test_dedup rename to test;
    

    이것은 당신이에 의해 순서를 사용하는 경우, 널 (null) 값이 null이 아닌 값 뒤에 정렬됩니다 기능을 사용하고 있습니다.

    create table test (rowid_ varchar(5), t1 varchar(5), t2 varchar(5));
    insert into test  values ('12345', 'ssdlh', null);
    insert into test  values ('12345', 'ssdlh', 'lhbzj');
    create table test_dedup as
    select rowid_, t1, t2 from
    (select *
      , row_number() over (partition by rowid_ order by t1, t2) as cn
      from  test)
     where cn =1
     ;
    
    -----optional
    --remove original table and rename dedup table to previous table
    --this is not recommend in dev or qa. DROP table test; Alter table test_dedup rename to test;
    
  15. ==============================

    15.문제는 오늘에 란은, 기존의 답변을 아무도 나에게 도움이되지 않습니다. 당신이 당신의 테이블 your_table라는 이름의 중복 제거하려는 가정합니다.

    문제는 오늘에 란은, 기존의 답변을 아무도 나에게 도움이되지 않습니다. 당신이 당신의 테이블 your_table라는 이름의 중복 제거하려는 가정합니다.

    1 단계 : deduped 값을 갖는 새 테이블을 만듭니다

    에 StackOverflow에 다른 곳에서이 코드를 차용하지만 다시 찾을 수가 없어 할 수 있습니다. 그것은 PostgreSQL을에 대해 잘 작동합니다. 그것은 (COL1, COL2)이 고유 테이블 your_table_deduped을 만듭니다.

    CREATE TABLE your_table_deduped AS
    SELECT * FROM your_table WHERE ctid NOT IN
    (SELECT ctid FROM
      (SELECT ctid, ROW_NUMBER() OVER
        (PARTITION BY col1, col2 ORDER BY ctid) AS rnum
      FROM your_table) t
    WHERE t.rnum > 1);
    

    2 단계 다음 deduped 사본과 함께 첫 번째 테이블을 교체

    그것은 당신의 테이블에 등 인덱스, 제약 조건을 유지하기 위해 우리가 할 수 있기 때문에 우리는이 단계에서 값을 삭제합니다.

    DELETE FROM your_table;
    INSERT INTO your_table
    SELECT * FROM your_table_deduped;
    

    3 단계 : deduped 사본을 삭제

    DROP TABLE site_daily_kpis_dedup;
    

    그리고 짜잔, 당신은 당신의 테이블을 중복 제거했다!

  16. ==============================

    16.

    delete from yourTable 
    where Id not in (
        select min(id) 
        from yourTable
        group by <Unique Columns>
    )
    

    여기서 id는 테이블의 고유 ID 어떤입니다. (CUSTOMERNUMBER 또는 무엇이든 될 수 있음)

    당신이 고유 ID가없는 경우, 당신은 하나 (모든 SQL의 테이블이 이미 첫 번째 열로 ID가 있어야 추가 할 수 있지만,

    ALTER TABLE yourTable
    ADD Id int identity(1,1)
    

    당신의 삭제 (위) 수행 한 후 열을 놓습니다.

    완전히 새로운 테이블을 생성하거나, 내가 본 다른 비밀 물건들보다 더 나은. 여기에 코멘트에서와 거의 동일합니다, 그러나 이것은 내가 년 동안 한 일이다.

  17. from https://stackoverflow.com/questions/2230295/whats-the-best-way-to-dedupe-a-table by cc-by-sa and MIT license