Để triển khai UDF của Khoảng cách Levenshtein thuật toán bạn có thể muốn kiểm tra " codejanitor.com:Khoảng cách Levenshtein dưới dạng một hàm được lưu trữ trong MySQL ":
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
Bây giờ, hãy tạo một trường hợp thử nghiệm, sử dụng dữ liệu bạn đã cung cấp trong câu hỏi của mình:
CREATE TABLE table_a (name varchar(20));
CREATE TABLE table_b (name varchar(20));
INSERT INTO table_a VALUES('Olde School');
INSERT INTO table_a VALUES('New School');
INSERT INTO table_a VALUES('Other, C.S. School');
INSERT INTO table_a VALUES('Main School');
INSERT INTO table_a VALUES('Too Cool for School');
INSERT INTO table_b VALUES('Old School');
INSERT INTO table_b VALUES('New ES');
INSERT INTO table_b VALUES('Other School');
INSERT INTO table_b VALUES('Main School');
INSERT INTO table_b VALUES('Hardknocks School');
Sau đó:
SELECT *
FROM table_a a
LEFT JOIN table_b b ON (a.name = b.name);
Rõ ràng là trả về một trận đấu trong đó tên trường khớp chính xác:
+---------------------+-------------+
| name | name |
+---------------------+-------------+
| Olde School | NULL |
| New School | NULL |
| Other, C.S. School | NULL |
| Main School | Main School |
| Too Cool for School | NULL |
+---------------------+-------------+
5 rows in set (0.00 sec)
Bây giờ chúng ta có thể thử sử dụng LEVENSHTEIN
hàm trả về tên trường có chỉnh sửa khoảng cách
từ 2 ký tự trở xuống:
SELECT *
FROM table_a a
LEFT JOIN table_b b ON (LEVENSHTEIN(a.name, b.name) <= 2);
+---------------------+-------------+
| name | name |
+---------------------+-------------+
| Olde School | Old School |
| New School | NULL |
| Other, C.S. School | NULL |
| Main School | Main School |
| Too Cool for School | NULL |
+---------------------+-------------+
5 rows in set (0.08 sec)
Hiện đang sử dụng <= 3
làm ngưỡng khoảng cách chỉnh sửa:
SELECT *
FROM table_a a
LEFT JOIN table_b b ON (LEVENSHTEIN(a.name, b.name) <= 3);
Chúng tôi nhận được kết quả sau:
+---------------------+--------------+
| name | name |
+---------------------+--------------+
| Olde School | Old School |
| Olde School | Other School |
| New School | Old School |
| Other, C.S. School | NULL |
| Main School | Main School |
| Too Cool for School | NULL |
+---------------------+--------------+
6 rows in set (0.06 sec)
Lưu ý cách lần này Olde School
cũng khớp với Other School
và New School
phù hợp với Old School
cũng. Đây có thể là dương tính giả và cho thấy rằng việc xác định ngưỡng là rất quan trọng để tránh các kết quả phù hợp không chính xác.
Một kỹ thuật phổ biến để giải quyết vấn đề này là xem xét độ dài của các chuỗi khi áp dụng một ngưỡng. Trên thực tế, trang web đó Tôi đã trích dẫn cho việc triển khai này
cũng cung cấp LEVENSHTEIN_RATIO
hàm trả về tỷ lệ (dưới dạng phần trăm) của sự khác biệt chỉnh sửa dựa trên độ dài của các chuỗi.