Вот мысль, используя SOUNDEX. SOUNDEX действительно паршивая функция и, конечно, не панацея, но она может уменьшить набор данных, содержащий тысячи ошибок, до набора данных, содержащего сотни ошибок.
В остальном мы можем Посмотрите на такие вещи, как расстояние Левенштейна, но, в конечном счете, вам понадобится ручной подход в некоторой степени ...
DROP TABLE IF EXISTS bad_data;
CREATE TABLE bad_data
(id SERIAL PRIMARY KEY
,string VARCHAR(12) NOT NULL
);
INSERT INTO bad_data (string) VALUES
('apple'),
('appl'),
('aple'),
('bana'),
('banana'),
('banna'),
('cat'),
('cot'),
('cta');
DROP TABLE IF EXISTS good_data;
CREATE TABLE good_data
(id SERIAL PRIMARY KEY
,string VARCHAR(12) NOT NULL UNIQUE
);
INSERT INTO good_data(string) VALUES
('apple'),
('banana'),
('cat');
SELECT *
FROM bad_data x
JOIN good_data y ON SOUNDEX(x.string) = SOUNDEX(y.string);
+----+--------+------+--------+
| id | string | id | string |
+----+--------+------+--------+
| 1 | apple | 1 | apple |
| 2 | appl | 1 | apple |
| 3 | aple | 1 | apple |
| 4 | bana | 2 | banana |
| 5 | banana | 2 | banana |
| 6 | banna | 2 | banana |
| 7 | cat | 3 | cat |
| 8 | cot | 3 | cat |
| 9 | cta | 3 | cat |
+----+--------+------+--------+