Se adicionar uma chave primária não for uma opção, uma abordagem seria armazenar as duplicatas DISTINCT em uma tabela temporária, excluir todos os registros duplicados da tabela existente e, em seguida, adicionar os registros de volta à tabela original da tabela temporária .
Por exemplo (escrito para SQL Server 2008, mas a técnica é a mesma para qualquer banco de dados):
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
Não tenho certeza se sqlite tem uma ROW_NUMBER()
função de tipo, mas se tiver, você também pode tentar algumas das abordagens listadas aqui: Excluir registros duplicados de uma tabela SQL sem uma chave primária