복붙노트

[SQL] 어떻게 SQL 서버에서 중복 행을 삭제하려면?

SQL

어떻게 SQL 서버에서 중복 행을 삭제하려면?

어떻게 더 고유 한 행 ID가 존재하지 않는 중복 행을 삭제할 수 있습니까?

내 테이블입니다

col1  col2 col3 col4 col5 col6 col7
john  1    1    1    1    1    1 
john  1    1    1    1    1    1
sally 2    2    2    2    2    2
sally 2    2    2    2    2    2

나는 중복 제거 후 다음 왼쪽 싶지 :

john  1    1    1    1    1    1
sally 2    2    2    2    2    2

나는 몇 가지 질의를 시도했지만 나는 그들이 내가 원하는 결과를 얻을하지 않는 한 행 ID를 가지고에 의존 생각합니다. 예를 들면 :

DELETE
FROM table
WHERE col1 IN (
    SELECT id
    FROM table
    GROUP BY id
    HAVING (COUNT(col1) > 1)
)

해결법

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

    1.열팽창 계수와 ROW_NUMBER 같은 나는 결합이 우리가, 삭제 (또는 갱신)하는 행을 볼 수 있으므로 단지 CTE SELECT * FROM하는 ... CTE에서 DELETE를 변경할 수로 :

    열팽창 계수와 ROW_NUMBER 같은 나는 결합이 우리가, 삭제 (또는 갱신)하는 행을 볼 수 있으므로 단지 CTE SELECT * FROM하는 ... CTE에서 DELETE를 변경할 수로 :

    WITH CTE AS(
       SELECT [col1], [col2], [col3], [col4], [col5], [col6], [col7],
           RN = ROW_NUMBER()OVER(PARTITION BY col1 ORDER BY col1)
       FROM dbo.Table1
    )
    DELETE FROM CTE WHERE RN > 1
    

    DEMO는 (결과는 다른, 나는 그것이 당신의 부분에 오타로 인해 있다고 가정)

    COL1    COL2    COL3    COL4    COL5    COL6    COL7
    john    1        1       1       1       1       1
    sally   2        2       2       2       2       2
    

    이 예 COL1 BY 때문에 파티션의 단일 컬럼 COL1하여 중복을 판단한다. 여러 열을 포함 할 경우 단순히 파티션 BY에 추가 :

    ROW_NUMBER()OVER(PARTITION BY Col1, Col2, ... ORDER BY OrderColumn)
    
  2. ==============================

    2.나는 SQL 서버 테이블에서 중복 행을 삭제하는 CTE를 선호

    나는 SQL 서버 테이블에서 중복 행을 삭제하는 CTE를 선호

    //codaffection.com/sql-server-article/delete-duplicate-rows-in-sql-server/ : 강력하게이 기사 :: HTTP를 수행하는 것이 좋습니다

    WITH CTE AS
    (
    SELECT *,ROW_NUMBER() OVER (PARTITION BY col1,col2,col3 ORDER BY col1,col2,col3) AS RN
    FROM MyTable
    )
    
    DELETE FROM CTE WHERE RN<>1
    
    WITH CTE AS
    (SELECT *,R=RANK() OVER (ORDER BY col1,col2,col3)
    FROM MyTable)
     
    DELETE CTE
    WHERE R IN (SELECT R FROM CTE GROUP BY R HAVING COUNT(*)>1)
    
  3. ==============================

    3.CTE와 ROW_NUMBER ()를 사용하지 않고 그냥이며, 예를 들어 여기 MAX 기능에 의해 그룹을 사용하여 기록을 삭제할 수 있습니다

    CTE와 ROW_NUMBER ()를 사용하지 않고 그냥이며, 예를 들어 여기 MAX 기능에 의해 그룹을 사용하여 기록을 삭제할 수 있습니다

    DELETE
    FROM MyDuplicateTable
    WHERE ID NOT IN
    (
    SELECT MAX(ID)
    FROM MyDuplicateTable
    GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3)
    
  4. ==============================

    4.

    DELETE from search
    where id not in (
       select min(id) from search
       group by url
       having count(*)=1
    
       union
    
       SELECT min(id) FROM search
       group by url
       having count(*) > 1
    )
    
  5. ==============================

    5.더 언급이없는 경우, 외래 키처럼, 당신은이 작업을 수행 할 수 있습니다. 개념의 증거를 테스트하고 테스트 데이터가 중복됩니다 때 나는 그것을 많이 할.

    더 언급이없는 경우, 외래 키처럼, 당신은이 작업을 수행 할 수 있습니다. 개념의 증거를 테스트하고 테스트 데이터가 중복됩니다 때 나는 그것을 많이 할.

    SELECT DISTINCT [col1],[col2],[col3],[col4],[col5],[col6],[col7]
    
    INTO [newTable]
    

    개체 탐색기로 이동하여 이전 테이블을 삭제합니다.

    이전 테이블의 이름으로 새 테이블의 이름을 바꿉니다.

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

    6.삭제 아래의 방법도 참조하십시오.

    삭제 아래의 방법도 참조하십시오.

    Declare @table table
    (col1 varchar(10),col2 int,col3 int, col4 int, col5 int, col6 int, col7 int)
    Insert into @table values 
    ('john',1,1,1,1,1,1),
    ('john',1,1,1,1,1,1),
    ('sally',2,2,2,2,2,2),
    ('sally',2,2,2,2,2,2)
    

    @table라는 이름의 샘플 테이블을 작성하고 주어진 데이터를로드.

    Delete  aliasName from (
    Select  *,
            ROW_NUMBER() over (Partition by col1,col2,col3,col4,col5,col6,col7 order by col1) as rowNumber
    From    @table) aliasName 
    Where   rowNumber > 1
    
    Select * from @table
    

    참고 :이 부분에 의해 분할의 모든 열을 제공하는 경우로 다음 순서는 많은 의미가 없습니다.

    나는 질문 3 년 전 요청합니다 알고, 내 대답은 팀이 게시 된 것을의 또 다른 버전입니다,하지만 그냥 넣다 게시하는 것은 누군가를 위해 도움이됩니다.

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

    7.마이크로 소프트는 중복을 제거하는 방법에 대한 참 스피 깔끔한 가이드가 있습니다. http://support.microsoft.com/kb/139444을 확인

    마이크로 소프트는 중복을 제거하는 방법에 대한 참 스피 깔끔한 가이드가 있습니다. http://support.microsoft.com/kb/139444을 확인

    간단히, 여기 삭제하는 몇 행이있을 때 중복을 제거하는 가장 쉬운 방법은 다음과 같습니다

    SET rowcount 1;
    DELETE FROM t1 WHERE myprimarykey=1;
    

    myprimarykey의 행에 대한 식별자이다.

    난 단지 중복 된 두 행을했기 때문에 나는 1 행 개수를 설정합니다. 나는 3 개 행이 다음 중복 있었다면 나는 그것이 보는 것을 처음 두를 삭제 그래서 2 세트의 행 개수를 만 T1 테이블에서 하나의 잎 것입니다.

    이 사람을 도움이되기를 바랍니다

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

    8.사용하려고 :

    사용하려고 :

    SELECT linkorder
        ,Row_Number() OVER (
            PARTITION BY linkorder ORDER BY linkorder DESC
            ) AS RowNum
    FROM u_links
    

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

    9.위의 제안 된 솔루션을 시도 후, 중소 테이블에 대한 그 작품. 나는 매우 큰 테이블에 대한 해당 솔루션을 제안 할 수 있습니다. 이후이 반복에서 실행됩니다.

    위의 제안 된 솔루션을 시도 후, 중소 테이블에 대한 그 작품. 나는 매우 큰 테이블에 대한 해당 솔루션을 제안 할 수 있습니다. 이후이 반복에서 실행됩니다.

    SET IDENTITY_INSERT LargeSourceTable ON DECLARE @PageNumber INT AS, AS @RowspPage INT DECLARE의 @TotalRows AS INT @dt VARCHAR 선언 (19) SET @PageNumber = 0 SET @RowspPage = 1000000 @TotalRows 선택 = LargeSourceTable_TEMP에서 (*) 계수

    While ((@PageNumber - 1) * @RowspPage < @TotalRows )
    Begin
        begin transaction tran_inner
            ; with cte as
            (
                SELECT * FROM LargeSourceTable_TEMP ORDER BY ID
                OFFSET ((@PageNumber) * @RowspPage) ROWS
                FETCH NEXT @RowspPage ROWS ONLY
            )
    
            INSERT INTO LargeSourceTable 
            (
                 ID                     
                ,[CreateDate]       
                ,[Column1]   
                ,[Column2] 
                ,[Column3]       
            )       
            select 
                 ID                     
                ,[CreateDate]       
                ,[Column1]   
                ,[Column2] 
                ,[Column3]       
            from cte
    
        commit transaction tran_inner
    
        PRINT 'Page: ' + convert(varchar(10), @PageNumber)
        PRINT 'Transfered: ' + convert(varchar(20), @PageNumber * @RowspPage)
        PRINT 'Of: ' + convert(varchar(20), @TotalRows)
    
        SELECT @dt = convert(varchar(19), getdate(), 121)
        RAISERROR('Inserted on: %s', 0, 1, @dt) WITH NOWAIT
        SET @PageNumber = @PageNumber + 1
    End
    

    SET IDENTITY_INSERT LargeSourceTable OFF

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

    10.MySQL은 두 가지 해결책이 있습니다 :

    MySQL은 두 가지 해결책이 있습니다 :

    A) DELETE 사용하여 삭제 중복 행은 문을 가입

    DELETE t1 FROM contacts t1
    INNER JOIN contacts t2 
    WHERE 
        t1.id < t2.id AND 
        t1.email = t2.email;
    

    이 쿼리는 연락처 테이블을 두 번, 따라서, 테이블 별칭 T1과 T2를 사용하여 참조합니다.

    출력은 다음과 같습니다

    혹시 중복 행을 삭제하려면 가장 낮은 ID를 유지, 당신은 다음과 같은 문장을 사용할 수 있습니다 :

    DELETE c1 FROM contacts c1
    INNER JOIN contacts c2 
    WHERE
        c1.id > c2.id AND 
        c1.email = c2.email;
    

       

    B) 중간 테이블을 사용하여 삭제 중복 행

    쇼에게 중간 테이블을 사용하여 중복 행을 제거하는 단계를 수행 :

    구조는 중복 행 삭제를 원래의 테이블과 같은과 새로운 테이블을 작성하십시오.

    바로 테이블에 원래 테이블에서 2. 별개의 행.

    바로 테이블에 원래 테이블에서 3. 별개의 행.

     

    구조 새 테이블 만들기 1 단계는 원래 테이블과 동일합니다 :

    CREATE TABLE source_copy LIKE source;
    

    단계 새 테이블에 원본 테이블에서 2. 별개의 행 :

    INSERT INTO source_copy
    SELECT * FROM source
    GROUP BY col; -- column that has duplicate values
    

    단계는 원래 테이블을 삭제하고 원래 하나에 즉시 테이블의 이름을 변경합니다

    DROP TABLE source;
    ALTER TABLE source_copy RENAME TO source;
    

    출처 : http://www.mysqltutorial.org/mysql-delete-duplicate-rows/

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

    11.

    -- this query will keep only one instance of a duplicate record.
    ;WITH cte
         AS (SELECT ROW_NUMBER() OVER (PARTITION BY col1, col2, col3-- based on what? --can be multiple columns
                                           ORDER BY ( SELECT 0)) RN
             FROM   Mytable)
    
    
    
    delete  FROM cte
    WHERE  RN > 1
    
  12. ==============================

    12.그런 다음 기록 중 하나를 보유하고 나머지는 삭제 필드 (들)에 따라 중복 레코드가 그룹에 필요합니다. 예를 들면 :

    그런 다음 기록 중 하나를 보유하고 나머지는 삭제 필드 (들)에 따라 중복 레코드가 그룹에 필요합니다. 예를 들면 :

    DELETE prg.Person WHERE Id IN (
    SELECT dublicateRow.Id FROM
    (
    select MIN(Id) MinId, NationalCode
     from  prg.Person group by NationalCode  having count(NationalCode ) > 1
     ) GroupSelect
     JOIN  prg.Person dublicateRow ON dublicateRow.NationalCode = GroupSelect.NationalCode 
     WHERE dublicateRow.Id <> GroupSelect.MinId)
    
  13. ==============================

    13.

    with myCTE
    as
    
    (
    select productName,ROW_NUMBER() over(PARTITION BY productName order by slno) as Duplicate from productDetails
    )
    Delete from myCTE where Duplicate>1
    
  14. ==============================

    14.https://support.microsoft.com/en-us/help/139444/how-to-remove-duplicate-rows-from-a-table-in-sql-server 참조하여

    https://support.microsoft.com/en-us/help/139444/how-to-remove-duplicate-rows-from-a-table-in-sql-server 참조하여

    제거 중복의 개념은 포함한다

    단계별

  15. ==============================

    15.임시 테이블에 열을 추가 할 수있는 기능이있는 경우, 이것은 나를 위해 일한 솔루션했다 :

    임시 테이블에 열을 추가 할 수있는 기능이있는 경우, 이것은 나를 위해 일한 솔루션했다 :

    ALTER TABLE dbo.DUPPEDTABLE ADD RowID INT NOT NULL IDENTITY(1,1)
    

    그런 다음 수행 A 최소 및 GROUP BY의 조합을 사용하여 삭제

    DELETE b
    FROM dbo.DUPPEDTABLE b
    WHERE b.RowID NOT IN (
                         SELECT MIN(RowID) AS RowID
                         FROM dbo.DUPPEDTABLE a WITH (NOLOCK)
                         GROUP BY a.ITEM_NUMBER,
                                  a.CHARACTERISTIC,
                                  a.INTVALUE,
                                  a.FLOATVALUE,
                                  a.STRINGVALUE
                     );
    

    삭제가 제대로 수행되었는지 확인합니다 :

    SELECT a.ITEM_NUMBER,
        a.CHARACTERISTIC,
        a.INTVALUE,
        a.FLOATVALUE,
        a.STRINGVALUE, COUNT(*)--MIN(RowID) AS RowID
    FROM dbo.DUPPEDTABLE a WITH (NOLOCK)
    GROUP BY a.ITEM_NUMBER,
        a.CHARACTERISTIC,
        a.INTVALUE,
        a.FLOATVALUE,
        a.STRINGVALUE
    ORDER BY COUNT(*) DESC 
    

    결과는 마지막으로 ROWID 열을 제거 1보다 카운트 큰 아무런 행이 없어야합니다 :

    ALTER TABLE dbo.DUPPEDTABLE DROP COLUMN RowID;
    
  16. ==============================

    16.테이블 거대한 (기록의 수백만)에서 중복을 삭제하면 시간이 오래 걸릴 수 있습니다. 난 당신이 아니라 삭제보다 선택한 행의 임시 테이블에 대량 삽입을하는 것이 좋습니다.

    테이블 거대한 (기록의 수백만)에서 중복을 삭제하면 시간이 오래 걸릴 수 있습니다. 난 당신이 아니라 삭제보다 선택한 행의 임시 테이블에 대량 삽입을하는 것이 좋습니다.

    --REWRITING YOUR CODE(TAKE NOTE OF THE 3RD LINE) WITH CTE AS(SELECT NAME,ROW_NUMBER() 
    OVER (PARTITION BY NAME ORDER BY NAME) ID FROM @TB) SELECT * INTO #unique_records FROM 
    CTE WHERE ID =1;
    
  17. ==============================

    17.그것은 SQL 서버에서 여러 가지 방법으로 수행 할 수 있습니다 그렇게 할 수있는 가장 간단한 방법은 다음과 같습니다 새 임시 테이블에 중복 행 테이블에서 별개의 행을 삽입합니다. 그런 다음 아래 그림과 같이 더 중복이없는 임시 테이블에서 모든 데이터를 삽입 한 후 중복 행 테이블의 모든 데이터를 삭제합니다.

    그것은 SQL 서버에서 여러 가지 방법으로 수행 할 수 있습니다 그렇게 할 수있는 가장 간단한 방법은 다음과 같습니다 새 임시 테이블에 중복 행 테이블에서 별개의 행을 삽입합니다. 그런 다음 아래 그림과 같이 더 중복이없는 임시 테이블에서 모든 데이터를 삽입 한 후 중복 행 테이블의 모든 데이터를 삭제합니다.

    select distinct * into #tmp From table
       delete from table
       insert into table
       select * from #tmp drop table #tmp
    
       select * from table
    

    공통 테이블 표현식을 사용하여 삭제 중복 행 (CTE)

    With CTE_Duplicates as 
    (select id,name , row_number() 
    over(partition by id,name order by id,name ) rownumber  from table  ) 
    delete from CTE_Duplicates where rownumber!=1
    
  18. ==============================

    18.한 번에 정보를 잃지 않고 중복 행을 제거하는 또 다른 방법은 다음과 같다 :

    한 번에 정보를 잃지 않고 중복 행을 제거하는 또 다른 방법은 다음과 같다 :

    delete from dublicated_table t1 (nolock)
    join (
        select t2.dublicated_field
        , min(len(t2.field_kept)) as min_field_kept
        from dublicated_table t2 (nolock)
        group by t2.dublicated_field having COUNT(*)>1
    ) t3 
    on t1.dublicated_field=t3.dublicated_field 
        and len(t1.field_kept)=t3.min_field_kept
    
  19. ==============================

    19.오 와우, 나는 그들이 전문가 '모든 CTE에 대한 답변과 임시 테이블 등처럼, 준비 모든 답변에 의해 그렇게 바보가 된 기분

    오 와우, 나는 그들이 전문가 '모든 CTE에 대한 답변과 임시 테이블 등처럼, 준비 모든 답변에 의해 그렇게 바보가 된 기분

    그리고 모든 나는 단순히 MAX를 사용하여 ID 열을 집계 한 작업을 진행했다.

    DELETE FROM table WHERE col1 IN (
        SELECT MAX(id) FROM table GROUP BY id HAVING ( COUNT(col1) > 1 )
    )
    

    참고 :이 한 번에 중복 행 한 세트를 삭제합니다 당신이 그것을 중복 제거하기 위해 여러 번 실행해야 할 수도 있습니다.

  20. ==============================

    20.

    DECLARE @TB TABLE(NAME VARCHAR(100));
    INSERT INTO @TB VALUES ('Red'),('Red'),('Green'),('Blue'),('White'),('White')
    --**Delete by Rank**
    ;WITH CTE AS(SELECT NAME,DENSE_RANK() OVER (PARTITION BY NAME ORDER BY NEWID()) ID FROM @TB)
    DELETE FROM CTE WHERE ID>1
    SELECT NAME FROM @TB;
    --**Delete by Row Number** 
    ;WITH CTE AS(SELECT NAME,ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY NAME) ID FROM @TB)
    DELETE FROM CTE WHERE ID>1;
    SELECT NAME FROM @TB;
    
  21. ==============================

    21.

    DELETE FROM TBL1  WHERE ID  IN
    (SELECT ID FROM TBL1  a WHERE ID!=
    (select MAX(ID) from TBL1  where DUPVAL=a.DUPVAL 
    group by DUPVAL
    having count(DUPVAL)>1))
    
  22. from https://stackoverflow.com/questions/18390574/how-to-delete-duplicate-rows-in-sql-server by cc-by-sa and MIT license