sqlite 데이터베이스에서 중복 행 삭제 행이 중복됩니다. 즉, 모두 hash와 d같은

SQLite3에 3 천 6 백만 행의 거대한 테이블이 있습니다. 이 매우 큰 테이블에는 두 개의 열이 있습니다.

  • hash -텍스트
  • d -진짜

일부 행이 중복됩니다. 즉, 모두 hashd같은 값을 가지고있다. 두 해시가 동일하면의 값도 동일합니다 d. 그러나 두 개의 동일한 d‘이 두 개의 동일한 ‘을 의미하지는 않습니다 hash.

중복 된 행을 삭제하고 싶습니다. 기본 키 열이 없습니다.

이를 수행하는 가장 빠른 방법은 무엇입니까?



답변

행을 구별하는 방법이 필요합니다. 귀하의 의견에 따라 특수 rowid 열 을 사용할 수 있습니다 .

가장 낮은 유지하여 중복을 삭제하려면 rowid당을 (hash,d):

delete   from YourTable
where    rowid not in
         (
         select  min(rowid)
         from    YourTable
         group by
                 hash
         ,       d
         )


답변

가장 빠른 방법은 바로 데이터베이스를 사용하는 것입니다. 동일한 열이있는 새 테이블을 추가하고 적절한 제약 조건 (해시 / 실제 쌍에 대한 고유 인덱스?)을 사용하고 원래 테이블을 반복하고 레코드를 삽입하려고합니다. 제약 위반 오류를 무시하는 새 테이블 (예 : 예외가 발생할 때 계속 반복)

그런 다음 이전 테이블을 삭제하고 새 테이블을 이전 테이블로 이름을 바꿉니다.


답변

기본 키를 추가하는 것이 옵션이 아닌 경우 한 가지 방법은 중복 DISTINCT를 임시 테이블에 저장하고 기존 테이블에서 모든 중복 레코드를 삭제 한 다음 임시 테이블에서 원래 테이블에 레코드를 다시 추가하는 것입니다. .

예 (SQL Server 2008 용으로 작성되었지만 기술은 모든 데이터베이스에서 동일 함) :

DECLARE @original AS TABLE([hash] varchar(20), [d] float)
INSERT INTO @original VALUES('A', 1)
INSERT INTO @original VALUES('A', 2)
INSERT INTO @original VALUES('A', 1)
INSERT INTO @original VALUES('B', 1)
INSERT INTO @original VALUES('C', 1)
INSERT INTO @original VALUES('C', 1)

DECLARE @temp AS TABLE([hash] varchar(20), [d] float)
INSERT INTO @temp
SELECT [hash], [d] FROM @original
GROUP BY [hash], [d]
HAVING COUNT(*) > 1

DELETE O
FROM @original O
JOIN @temp T ON T.[hash] = O.[hash] AND T.[d] = O.[d]

INSERT INTO @original
SELECT [hash], [d] FROM @temp

SELECT * FROM @original

sqlite에 ROW_NUMBER()유형 함수 가 있는지 확실 하지 않지만 여기에 나열된 방법 중 일부를 시도해 볼 수도 있습니다. 기본 키없이 SQL 테이블에서 중복 레코드 삭제


답변