从sqlite数据库删除重复的行


91

我在SQLite3中有一个巨大的表-3600万行。在这个很大的表中,有两列:

  • hash -文字
  • d -真实

一些行是重复的。也就是说,两者hashd具有相同的值。如果两个哈希值相同,则的值也相同d。但是,两个相同的d'并不意味着两个相同hash'。

我想删除重复的行。我没有主键列。

最快的方法是什么?


请将答案放在答案栏中。以后,您可以接受自己的答案。另请参阅接受答案如何工作?
jww

Answers:


120

您需要一种区分行的方法。根据您的评论,您可以为此使用特殊的rowid列

要通过保持最低的删除重复rowid(hash,d)

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

SQLite不允许您添加主键列,对吗?
补丁

sqlite> alter table dist add id integer primary key autoincrement; Error: Cannot add a PRIMARY KEY column
补丁

有趣!autoincrement但是,您需要的零件是零件,如果省略primary key零件,它是否可以工作?
2011年

sqlite> alter table dist add id integer autoincrement; Error: near "autoincrement": syntax error 编辑:SQLite确实有一个“ rowid”伪列类型thing,它会自动存在,我可以使用它吗?
补丁

1
delete from dist where rowid not in (select max(rowid) from dist group by hash); 似乎能解决问题!谢谢。
补丁

5

我猜最快的方法是使用数据库:添加具有相同列但具有适当约束(哈希/实数对的唯一索引?)的新表,遍历原始表并尝试在其中插入记录新表,忽略约束冲突错误(即在引发异常时继续迭代)。

然后删除旧表并将新表重命名为旧表。


我猜想,它不如简单地更改表那样优雅,但是,您的方法的一个真正好处是,您可以根据需要重新运行它多次,而不会涉及/破坏源数据,直到您对结果完全满意为止。
阿德里安·卡

1

如果添加主键不是一种选择,那么一种方法是将重复的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表中删除没有主键的重复记录


+1,不确定sqlite是否支持delete <alias> from <table> <alias>语法
Andomar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.