Siehe in diesem Artikel, wie Sie vielleicht implement Levenshtein distance in a MySQL stored function.
Für die Nachwelt den Vorschlag des Autors liegen, dies zu tun:
CREATE FUNCTION LEVENSHTEIN (s1 VARCHAR(255), s2 VARCHAR(255))
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
DECLARE s1_char CHAR;
DECLARE cv0, cv1 VARBINARY(256);
SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
IF s1 = s2 THEN
RETURN 0;
ELSEIF s1_len = 0 THEN
RETURN s2_len;
ELSEIF s2_len = 0 THEN
RETURN s1_len;
ELSE
WHILE j <= s2_len DO
SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
END WHILE;
WHILE i <= s1_len DO
SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
WHILE j <= s2_len DO
SET c = c + 1;
IF s1_char = SUBSTRING(s2, j, 1) THEN SET cost = 0; ELSE SET cost = 1; END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
IF c > c_temp THEN SET c = c_temp; END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
IF c > c_temp THEN SET c = c_temp; END IF;
SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
END WHILE;
SET cv1 = cv0, i = i + 1;
END WHILE;
END IF;
RETURN c;
END
Er liefert auch eine LEVENSHTEIN_RATIO Hilfsmethode, die das Verhältnis der verschiedenen/Gesamt Zeichen wertet, anstatt eine gerade Editierdistanz. Zum Beispiel, wenn es 60% ist, dann sind drei Fünftel der Zeichen in dem Quellwort verschieden von dem Zielwort.
CREATE FUNCTION LEVENSHTEIN_RATIO (s1 VARCHAR(255), s2 VARCHAR(255))
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE s1_len, s2_len, max_len INT;
SET s1_len = LENGTH(s1), s2_len = LENGTH(s2);
IF s1_len > s2_len THEN SET max_len = s1_len; ELSE SET max_len = s2_len; END IF;
RETURN ROUND((1 - LEVENSHTEIN(s1, s2)/max_len) * 100);
END
Auch für die Nachwelt ist dies Code von Jason Rust, die auf Code von Arnold Fribble basiert, der wiederum teilweise auf Arbeiten von Joseph Gama basiert. – webbiedave
D'oh. Irgendwie dachte ich, ich hätte den Autor erwähnt, aber offensichtlich nicht. Danke für das Ausfüllen der Lücken, @webbiedave. –
Danke für die UDF, es ist sehr nützlich. Aber wenn ich eine Abfrage wie "SELECT * FROM Tabelle WHERE HAVING LEVENSHTEIN ('Schlüsselwort', Feld) <3 (oder so)" in einer ~ 300k Zeile Tabelle, dauert es (offensichtlich) Alter zu vervollständigen. Ich habe auch versucht, die Zeilensuche innerhalb zu reduzieren (mit WHERE CHAR_LENGTH ('field') BETWEEN CHAR_LENGTH ('keyword') - 1 UND CHAR_LENGTH ('keyword') + 1) aber es liefert Ergebnisse in satte 35 Sekunden :) Do you (or andere) haben eine Idee, diese Abfrage zu beschleunigen? – Hazar