回答:
行を区別する方法が必要です。コメントに基づいて、そのために特別な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);
トリックを行うように見えます!ありがとう。
データベースをそのまま使用するのが最も速いと思います:同じ列を持つ新しいテーブルを追加しますが、適切な制約(ハッシュ/実際のペアの一意のインデックス)を使用して、元のテーブルを反復処理し、レコードを挿入してみます制約違反エラーを無視して新しいテーブルを作成します(つまり、例外が発生したときに繰り返し処理を続行します)。
次に、古いテーブルを削除して、新しい名前を古いテーブルに変更します。
主キーの追加がオプションではない場合、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テーブルから重複レコードを削除する
delete <alias> from <table> <alias>
ただし、sqliteが構文をサポートしているかどうかは不明