sql >> Database teknologi >  >> RDS >> Mysql

Hvordan kan jeg vælge lignende rækker i to forskellige tabeller i MySQL (er det muligt?)

Til en UDF-implementering af Levenshtein Distance algoritme du måske vil tjekke "codejanitor.com:Levenshtein Distance som en MySQL-lagret funktion ":

CREATE FUNCTION LEVENSHTEIN (s1 VARCHAR(255), s2 VARCHAR(255))RETURNERER INTDETERMINISTICBEGIN 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; HVIS s1 =s2 SÅ RETUR 0; ELSEIF s1_len =0 SÅ TILBAGE s2_len; ELSEIF s2_len =0 SÅ TILBAGE s1_len; ANDET MENS j <=s2_len DO SET cv1 =CONCAT(cv1, UNHEX(HEX(j))), j =j + 1; SLUT MENS; WHILE i <=s1_len DO SET s1_char =SUBSTRING(s1, i, 1), c =i, cv0 =UNHEX(HEX(i)), j =1; MENS j <=s2_len GØR SET c =c + 1; HVIS s1_char =UNDERSTRÆNG(s2, j, 1) SÅ SÆT omkostning =0; ANDET SÆT pris =1; AFSLUT HVIS; SET c_temp =CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + pris; HVIS c> c_temp SÅ SÆT c =c_temp; AFSLUT HVIS; SET c_temp =CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1; HVIS c> c_temp SÅ SÆT c =c_temp; AFSLUT HVIS; SET cv0 =CONCAT(cv0, UNHEX(HEX(c))), j =j + 1; SLUT MENS; SET cv1 =cv0, i =i + 1; SLUT MENS; AFSLUT HVIS; RETURN c;END 

Lad os nu bygge en testcase ved hjælp af de data, du har angivet i dit spørgsmål:

CREATE TABLE table_a (navn varchar(20));CREATE TABLE table_b (navn varchar(20));INSERT INTO table_a VALUES('Gamle Skole'); INSERT INTO table_a VALUES('New School');INSERT INTO table_a VALUES('Andet, C.S. School');INSERT INTO table_a VALUES('Main School');INSERT INTO table_a VALUES('For cool til skole');INSERT INTO table_b VALUES('Old School');INSERT INTO table_b VALUES('New ES');INSERT INTO table_b VALUES('Anden skole');INSERT INTO table_b VALUES('Main School');INSERT INTO table_b VALUES('Hardknocks School'); '); 

Så:

VÆLG *FRA table_a aLEFT JOIN table_b b ON (a.name =b.name); 

Returnerer naturligvis et match, hvor skolenavnene matcher nøjagtigt:

+----------------------+--------------+| navn | navn |+---------------------+-------------+| Olde Skole | NULL || Ny skole | NULL || Andet, C.S. Skole | NULL || Hovedskole | Hovedskole || For cool til skole | NULL |+---------------------+-------------+5 rækker i sæt (0,00 sek.)

Nu kan vi prøve at bruge LEVENSHTEIN funktion til at returnere skolenavne, der har en redigeringsafstand på 2 tegn eller færre:

VÆLG *FRA table_a aLEFT JOIN table_b b ON (LEVENSHTEIN(a.name, b.name) <=2);+------------------ ---+-------------+| navn | navn |+---------------------+-------------+| Olde Skole | Old School || Ny skole | NULL || Andet, C.S. Skole | NULL || Hovedskole | Hovedskole || For cool til skole | NULL |+---------------------+-------------+5 rækker i sæt (0,08 sek.) 

Bruger nu <=3 som en redigeringsafstandstærskel:

VÆLG *FRA table_a aLEFT JOIN table_b b ON (LEVENSHTEIN(a.name, b.name) <=3); 

Vi får følgende resultat:

+---------------------+---------+| navn | navn |+---------------------+--------------+| Olde Skole | Old School || Olde Skole | Anden Skole || Ny skole | Old School || Andet, C.S. Skole | NULL || Hovedskole | Hovedskole || For cool til skole | NULL |+----------------------+--------------+6 rækker i sæt (0,06 sek.)

Bemærk hvordan denne gang Olde Skole matchede også Anden skole og Ny skole matchede Old School såvel. Disse er sandsynligvis falsk positive og viser, at det er meget vigtigt at definere tærsklen for at undgå forkerte matches.

En almindelig teknik til at tackle dette problem er at tage længden af ​​strengene i betragtning, når du anvender en tærskel. Faktisk er webstedet, der Jeg citerede for denne implementering giver også en LEVENSHTEIN_RATIO funktion, som returnerer forholdet (som en procentdel) af redigeringsforskellen baseret på længden af ​​strengene.



  1. NextForm v3:Fem muligheder for data- og databasemigrering

  2. Sådan henter du tabellisten i databasen i Laravel 5.1

  3. Sådan rettes "COMMIT TRANSACTION-anmodningen har ingen tilsvarende BEGIN TRANSACTION" i SQL Server

  4. Hvordan vedligeholder jeg PHP-sessioner på tværs af flere domæner på den samme server?