Saya memiliki tabel besar - 36 juta baris - di SQLite3. Dalam tabel yang sangat besar ini, ada dua kolom:
hash
- teksd
- nyata
Beberapa baris merupakan duplikat. Artinya, keduanya hash
dan d
memiliki nilai yang sama. Jika dua hash identik, maka nilai dari d
. Namun demikian, dua hal yang identik d
tidak berarti dua hal yang identik hash
.
Saya ingin menghapus baris duplikat. Saya tidak memiliki kolom kunci utama.
Apa cara tercepat untuk melakukan ini?
Jawaban:
Anda membutuhkan cara untuk membedakan baris. Berdasarkan komentar Anda, Anda dapat menggunakan kolom rowid khusus untuk itu.
Untuk menghapus duplikat dengan mempertahankan nilai terendah
rowid
per(hash,d)
:delete from YourTable where rowid not in ( select min(rowid) from YourTable group by hash , d )
sumber
sqlite> alter table dist add id integer primary key autoincrement; Error: Cannot add a PRIMARY KEY column
autoincrement
, apakah berfungsi jika Anda menghilangkanprimary key
bagian tersebut?sqlite> alter table dist add id integer autoincrement;
Error: near "autoincrement": syntax error
Sunting: SQLite memang memiliki jenis kolom semu "rowid" yang secara otomatis ada di sana, dapatkah saya menggunakan ini?delete from dist where rowid not in (select max(rowid) from dist group by hash);
Tampaknya berhasil! Terima kasih.Saya kira yang tercepat adalah menggunakan database untuk itu: tambahkan tabel baru dengan kolom yang sama, tetapi dengan batasan yang tepat (indeks unik pada pasangan hash / nyata?), Ulangi melalui tabel asli dan coba masukkan catatan di tabel baru, mengabaikan kesalahan pelanggaran batasan (yaitu melanjutkan iterasi ketika pengecualian dimunculkan).
Kemudian hapus tabel lama dan ganti nama yang baru ke yang lama.
sumber
Jika menambahkan kunci utama bukan merupakan pilihan, maka salah satu pendekatannya adalah menyimpan duplikat berbeda dalam tabel temp, Hapus semua rekaman duplikat dari tabel yang sudah ada, lalu tambahkan rekaman kembali ke tabel asli dari tabel temp .
Misalnya (ditulis untuk SQL Server 2008, tetapi tekniknya sama untuk database apa pun):
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
Saya tidak yakin apakah sqlite memiliki
ROW_NUMBER()
fungsi tipe, tetapi jika ya, Anda juga dapat mencoba beberapa pendekatan yang tercantum di sini: Hapus catatan duplikat dari tabel SQL tanpa kunci utamasumber
delete <alias> from <table> <alias>
sintaksis