Вдруг кому пригодится, SOUNDEX EN\RU для MYSQL

Ирокез

бессмертный пони
Команда форума
Партнер клуба
Протестировал на выборке ~100.000 фраз, результат мне показался приемлимым. Если что не так отпишитесь, писал быстро, вполне возможно, что-то пропустил/упустил/не протестил. Спасибо.

PHP:
CREATE FUNCTION `METAPHONE`(Phrase VARCHAR(1000), Length INT) RETURNS varchar(400) CHARSET utf8
    NO SQL
    DETERMINISTIC
BEGIN
	DECLARE it int;
    DECLARE Chr CHAR;
    DECLARE Letter CHAR;
    DECLARE Result VARCHAR(400);
	SET it=1;
    SET Letter='';
    SET Phrase=UPPER(Phrase);
    SET Result='';
    
	while it<=LENGTH(Phrase) AND LENGTH(Result)<Length do
		SET Chr = MID(Phrase,it,1);
        IF Letter='' AND LOCATE(Chr,'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ') THEN 
			SET Letter = Chr; 
        END IF;    
			IF Chr='B' OR Chr='P' OR Chr='Б' OR Chr='П' THEN 
				SET Result = CONCAT(Result,'1'); 
        ELSEIF Chr='F' OR Chr='V' OR Chr='Ф' OR Chr='В' THEN 
			SET Result = CONCAT(Result,'2'); 
        ELSEIF Chr='C' OR Chr='K' OR Chr='S' OR Chr='С' OR Chr='З' OR Chr='Ц' THEN 
			SET Result = CONCAT(Result,'3'); 
        ELSEIF Chr='G' OR Chr='J' OR Chr='Г' OR Chr='К' OR Chr='Х' THEN 
			SET Result = CONCAT(Result,'4'); 
        ELSEIF Chr='Q' OR Chr='X' OR Chr='Z' OR Chr='Ж' OR Chr='Ш' OR Chr='Щ' OR Chr='Ч' THEN 
			SET Result = CONCAT(Result,'5'); 
        ELSEIF Chr='D' OR Chr='T' OR Chr='Д' OR Chr='Т' THEN 
			SET Result = CONCAT(Result,'6'); 
        ELSEIF Chr='L' OR Chr='Л' THEN 
			SET Result = CONCAT(Result,'7'); 
        ELSEIF Chr='M' OR Chr='N' OR Chr='М' OR Chr='Н' THEN 
			SET Result = CONCAT(Result,'8'); 
        ELSEIF Chr='R' OR Chr='Р' THEN 
			SET Result = CONCAT(Result,'9'); 
        ELSEIF Chr='О' OR Chr='Ы' OR Chr='А' OR Chr='Я'  THEN #А
			SET Result = CONCAT(Result,'@');  
        ELSEIF Chr='Ю' OR Chr='У' THEN #У
			SET Result = CONCAT(Result,'#'); 
        ELSEIF Chr='Е' OR Chr='Ё' OR Chr='Э' OR Chr='И' OR Chr='Й'  THEN #И
			SET Result = CONCAT(Result,'$');      
        END IF;    
		SET it = it+1;
    END WHILE;
RETURN CONCAT(Letter,IF(LENGTH(Result)<Length,RPAD(Result,Length-LENGTH(Result),'0'),Result));
END
 

Ирокез

бессмертный пони
Команда форума
Партнер клуба
Ммм, приемлемым? Фулскан?
Через virtual columns можно изобразить аналог функционального индекса.
Мне необходимо было для группирования фонетически похожих фраз с пока не определенным "загрублением". Виртуальные, вычисляемые - пока еще не мигрировал на 5.7, да и боюсь вставка большого числа строк с производительностью функций, превратиться в тот еще увлекательный процесс.
 
Сверху