Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Correspondance floue SQL

Une solution spécifique à un domaine assez rapide peut consister à calculer une similarité de chaîne à l'aide de SOUNDEX et une distance numérique entre 2 chaînes. Cela ne sera vraiment utile que si vous avez beaucoup de codes produit.

En utilisant un simple UDF comme ci-dessous, vous pouvez extraire les caractères numériques d'une chaîne afin que vous puissiez ensuite obtenir 2200 sur 'CLC 2200npk' et 1100 sur 'CLC 1100' afin que vous puissiez maintenant déterminer la proximité en fonction de la sortie SOUNDEX de chaque entrée ainsi que la proximité de la composante numérique de chaque entrée.

CREATE Function [dbo].[ExtractNumeric](@input VARCHAR(1000))
RETURNS INT
AS
BEGIN
    WHILE PATINDEX('%[^0-9]%', @input) > 0
    BEGIN
        SET @input = STUFF(@input, PATINDEX('%[^0-9]%', @input), 1, '')
    END
    IF @input = '' OR @input IS NULL
        SET @input = '0'
    RETURN CAST(@input AS INT)
END
GO

En ce qui concerne les algorithmes à usage général, il y en a quelques-uns qui pourraient vous aider avec plus ou moins de succès en fonction de la taille de l'ensemble de données et des exigences de performance. (les deux liens ont des implémentations TSQL disponibles)

  • Double Metaphone - Cet algo vous donnera une meilleure correspondance que soundex au détriment de la vitesse, mais il est vraiment bon pour la correction orthographique.
  • Distance de Levenshtein - Cela calculera le nombre d'appuis sur les touches nécessaires pour transformer une chaîne en une autre, par exemple pour passer de 'CLC 2200npk' à 'CLC 2200' est de 3, tandis que de 'CLC 2200npk' à 'CLC 1100' est 5.

Voici un article intéressant qui applique les deux algos ensemble et qui peut vous donner quelques idées.

Eh bien, j'espère que cela aide un peu.

EDIT :Voici une implémentation partielle de la distance de Levenshtein beaucoup plus rapide (lisez le message, il ne renverra pas exactement les mêmes résultats que le résultat normal). Sur ma table de test de 125 000 lignes, il s'exécute en 6 secondes contre 60 secondes pour le premier auquel j'ai lié.