Newsgroup: it.comp.www.php
Titolo: Trovare record simili

Un saluto a tutti. Ho questo problema. In una tabella sono stati memorizzati 
una serie di nomi e cognomi. Per errore qualche nome è stato ripetuto con 
magari una sola lettera diversa. Il quesito è questo. E' possibile con una 
funzione o qualcosa di simile trovare quei record il cui contenuto è non 
uguale ma molto simile. Grazie a tutti. 

 tutti.
Puoi provare con una ricerca FULL TEXT, ciclando per tutti i record,
oppure estrai i valori in un array ed applica un algoritmo di
Approximate String Matching (vedi
http://www2.toki.or.id/book/AlgDesignManual/BOOK/BOOK2/NODE46.HTM#SECTIO
N02313000000000000000) che permette di individuare i pattern piu'
simili a quello fornito (es. utile per i controllori di ortografia).
-- 
Vuoi distribuire il tuo sito web su CD/DVD?
Prova 
http://www.dwebpro.com/
Vuoi diventare un esperto analista PHP/MySQL?
Vieni a fare uno stage con noi: 
http://www.creativepark.it/stage/



In PHP? Si', ma e' lunga; dell'ordine di n^2. Si puo' semplificare su
Linux installando un DLBO, non so su Windows, e creare la funzione di
Levenshtein in MySQL.
Altrimenti, ti tocca tradurre in PHP questo pseudocodice, che calcola
la distanza di Levenshtein e seleziona TUTTI i record (con MySQL e la
funziona dinamica potevi mettere WHERE LEVENSHTEIN(a.$field,b.$field)
< $CRITICAL_DISTANCE) AND... selezionando solo i record papabili):
	define(CRITICAL_DISTANCE, boh?);
	define(CRITICAL_FREQUENCY, 2);
	$fields = array('nome','cognome');
	foreach($fields as $field)
	{
		SQLExec("CREATE TEMPORARY TABLE puppa SELECT $field AS
			fld, COUNT(*) AS f FROM table GROUP BY $field;");
		$query = "SELECT a.$field AS src, a.f AS fa, b.$field AS
dst, b.f AS fb FROM puppa AS a JOIN puppa AS b WHERE a.$field !=
b.$field;";
		$exec = SQLExec($query);
		while($tuple = SQLFetchTuple($exec))
		{
			$dist = levenshtein($tuple['src'], $tuple['dst']);
			if ($dist > WARNING_DISTANCE)
				continue;
			if ($dist > CRITICAL_DISTANCE)
			{
				print "$tuple[src] and $tuple[dst] were
candidate, but their distance $dist does not warrant fixing<br />";
				continue;
			}
			// Rimpiazzo quello dei due che e' usato meno.
			if ($tuple['fa'] < $tuple['fb'])
			{
				$old = $tuple['src'];
				$new = $tuple['dst'];
				$frq = $tuple['fa'];
			}
			else
			{
				$old = $tuple['dst'];
				$new = $tuple['src'];
				$frq = $tuple['fb'];
			}
			// Ora se un errore e' successo una sola
			// volta passi. Ma, per esempio, "Maria"
			// NON E' un typo al posto di "Mario"!
			if ($frq < CRITICAL_FREQUENCY)
			{
				// If we meet little Bobby Tables
				// 
http://xkcd.com/327/
				$old = SQLEscape($old);
				$new = SQLEscape($new);
					SQLExec("UPDATE table SET
$field='$new' WHERE $field='$old';");
				print "$old is used only $frq times --
typo assumed, changed to '$new'<br />";
			}
			else
			{
				print "$old / $new but $old is used $frq
times -- assuming it's correct, leaving it alone<br />";
			}
		}
		SQLFree($exec);
		SQLExec("DROP TABLE puppa;");
	}
...piu' o meno. E prima fai un backup :-)
Leonardo
-- 
While ordinarily valid that being widespread does not make a statement
true, I feel that the diffusion of anti-evolutionary beliefs does pose
a strong argument for Darwin having been, indeed, sorely mistaken.


l'avevo gia' provata ma con scarsi risultati forse  dipende dal fatto che 
non so giocarci??? :-) accetto spunti. grazie 

 ha scritto nel messaggio 
news:fp5to35nuntbq5bso...@4ax.com...

ti ringrazio provero'. 


ho colto il senso del consiglio, ma non sono in grado di applicarlo :-(. 
grazie lo stesso