У меня есть огромная таблица - 36 миллионов строк - в SQLite3. В этой очень большой таблице есть два столбца:
hash
- текстd
- настоящий
Некоторые строки дублируются. То есть оба hash
и d
имеют одинаковые значения. Если два хэша идентичны, то значения d
. Однако два одинаковых d
не означают двух одинаковых hash
.
Я хочу удалить повторяющиеся строки. У меня нет столбца первичного ключа.
Как это сделать быстрее всего?
Ответы:
Вам нужен способ различать строки. Основываясь на вашем комментарии, вы можете использовать для этого специальный столбец rowid .
Для удаления дубликатов, сохраняя низкий
rowid
пер(hash,d)
:delete from YourTable where rowid not in ( select min(rowid) from YourTable group by hash , d )
источник
sqlite> alter table dist add id integer primary key autoincrement; Error: Cannot add a PRIMARY KEY column
autoincrement
, но работает ли она, если вы ее пропуститеprimary key
?sqlite> alter table dist add id integer autoincrement;
Error: near "autoincrement": syntax error
Изменить: SQLite имеет тип псевдоколонки "rowid", который автоматически присутствует, могу ли я использовать это?delete from dist where rowid not in (select max(rowid) from dist group by hash);
Кажется, трюк! Спасибо.Думаю, самым быстрым было бы использовать для этого саму базу данных: добавить новую таблицу с теми же столбцами, но с соответствующими ограничениями (уникальный индекс для пары хэш / реальная?), Перебрать исходную таблицу и попытаться вставить записи в новую таблицу, игнорируя ошибки нарушения ограничений (т.е. продолжать итерацию при возникновении исключений).
Затем удалите старую таблицу и переименуйте новую в старую.
источник
Если добавление первичного ключа не является вариантом, то один из подходов - сохранить дубликаты 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 без первичного ключаисточник
delete <alias> from <table> <alias>
синтаксис