Se l'aggiunta di una chiave primaria non è un'opzione, un approccio sarebbe quello di memorizzare i duplicati DISTINCT in una tabella temporanea, eliminare tutti i record duplicati dalla tabella esistente, quindi aggiungere nuovamente i record nella tabella originale dalla tabella temporanea .
Ad esempio (scritto per SQL Server 2008, ma la tecnica è la stessa per qualsiasi database):
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
Non sono sicuro che sqlite abbia una ROW_NUMBER()
funzione di tipo, ma se lo fa potresti anche provare alcuni degli approcci elencati qui: Elimina i record duplicati da una tabella SQL senza una chiave primaria