Levenshtein दूरी के UDF कार्यान्वयन के लिए एल्गोरिदम आप "codejanitor.com:Levenshtein दूरी एक 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
अब आपके द्वारा अपने प्रश्न में दिए गए डेटा का उपयोग करके एक परीक्षण केस बनाते हैं:
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');
फिर:
SELECT *
FROM table_a a
LEFT JOIN table_b b ON (a.name = b.name);
स्पष्ट रूप से एक मैच लौटाता है जहां स्कूल के नाम बिल्कुल मेल खाते हैं:
+---------------------+-------------+
| 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)
अब हम LEVENSHTEIN
. का उपयोग करने का प्रयास कर सकते हैं दूरी संपादित करें
वाले स्कूल के नाम वापस करने के लिए फ़ंक्शन 2 या उससे कम वर्णों में से:
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)
अब <= 3
. का उपयोग कर रहे हैं एक संपादन दूरी सीमा के रूप में:
SELECT *
FROM table_a a
LEFT JOIN table_b b ON (LEVENSHTEIN(a.name, b.name) <= 3);
हमें निम्नलिखित परिणाम मिलते हैं:
+---------------------+--------------+
| 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)
ध्यान दें कि इस बार कैसे Olde School
Other School
. से भी मेल खाता है , और New School
मिलान Olde School
भी। ये शायद गलत सकारात्मक हैं, और यह दर्शाता है कि गलत मिलान से बचने के लिए दहलीज को परिभाषित करना बहुत महत्वपूर्ण है।
इस समस्या से निपटने के लिए एक सामान्य तकनीक थ्रेशोल्ड लागू करते समय स्ट्रिंग्स की लंबाई को ध्यान में रखना है। वास्तव में, साइट मैंने इस कार्यान्वयन का हवाला दिया
एक LEVENSHTEIN_RATIO
भी प्रदान करता है फ़ंक्शन जो स्ट्रिंग की लंबाई के आधार पर संपादन अंतर का अनुपात (प्रतिशत के रूप में) देता है।