Ich habe eine riesige Tabelle - 36 Millionen Zeilen - in SQLite3. In dieser sehr großen Tabelle gibt es zwei Spalten:
hash
- Textd
- Real
Einige der Zeilen sind Duplikate. Das heißt, beide hash
und d
haben die gleichen Werte. Wenn zwei Hashes identisch sind, sind auch die Werte von identisch d
. Zwei identische d
implizieren jedoch nicht zwei identische hash
.
Ich möchte die doppelten Zeilen löschen. Ich habe keine Primärschlüsselspalte.
Was ist der schnellste Weg, dies zu tun?
Antworten:
Sie benötigen eine Möglichkeit, die Zeilen zu unterscheiden. Basierend auf Ihrem Kommentar können Sie dafür die spezielle Rowid-Spalte verwenden .
So löschen Sie Duplikate von den niedrigsten zu halten
rowid
pro(hash,d)
:quelle
sqlite> alter table dist add id integer primary key autoincrement; Error: Cannot add a PRIMARY KEY column
autoincrement
, funktioniert es, wenn Sie denprimary key
Teil weglassen ?sqlite> alter table dist add id integer autoincrement;
Error: near "autoincrement": syntax error
Bearbeiten: SQLite hat ein Pseudo-Spaltentyp "rowid", der automatisch vorhanden ist. Kann ich das verwenden?delete from dist where rowid not in (select max(rowid) from dist group by hash);
Scheint den Trick zu machen! Vielen Dank.Ich denke, am schnellsten wäre es, genau die Datenbank dafür zu verwenden: Fügen Sie eine neue Tabelle mit denselben Spalten hinzu, aber mit den richtigen Einschränkungen (ein eindeutiger Index für Hash / Real-Paar?), Durchlaufen Sie die ursprüngliche Tabelle und versuchen Sie, Datensätze einzufügen Die neue Tabelle ignoriert Fehler bei der Verletzung von Einschränkungen (dh setzt die Iteration fort, wenn Ausnahmen ausgelöst werden).
Löschen Sie dann die alte Tabelle und benennen Sie die neue in die alte um.
quelle
Wenn das Hinzufügen eines Primärschlüssels keine Option ist, besteht ein Ansatz darin, die Duplikate DISTINCT in einer temporären Tabelle zu speichern, alle duplizierten Datensätze aus der vorhandenen Tabelle zu löschen und die Datensätze dann wieder aus der temporären Tabelle in die ursprüngliche Tabelle einzufügen .
Zum Beispiel (geschrieben für SQL Server 2008, aber die Technik ist für jede Datenbank gleich):
Ich bin nicht sicher, ob SQLite eine Typfunktion hat
ROW_NUMBER()
, aber wenn dies der Fall ist, können Sie auch einige der hier aufgeführten Ansätze ausprobieren: Löschen Sie doppelte Datensätze aus einer SQL-Tabelle ohne Primärschlüsselquelle
delete <alias> from <table> <alias>
Syntax unterstützt