sql >> Database >  >> RDS >> Sqlserver

SQL Fuzzy Matching

Een vrij snelle domeinspecifieke oplossing kan zijn om een ​​stringovereenkomst te berekenen met SOUNDEX en een numerieke afstand tussen 2 strings. Dit helpt alleen als je veel productcodes hebt.

Met behulp van een eenvoudige UDF zoals hieronder kunt u de numerieke tekens uit een tekenreeks halen, zodat u vervolgens 2200 uit 'CLC 2200npk' en 1100 uit 'CLC 1100' kunt halen, zodat u nu de nabijheid kunt bepalen op basis van de SOUNDEX-uitvoer van elke invoer evenals de nabijheid van de numerieke component van elke invoer.

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

Wat algoritmen voor algemene doeleinden betreft, zijn er een paar die u met wisselend succes kunnen helpen, afhankelijk van de grootte van de dataset en de prestatie-eisen. (beide links hebben TSQL-implementaties beschikbaar)

  • Dubbele metafoon - Deze algo geeft je een betere match dan soundex ten koste van de snelheid, het is echter echt goed voor spellingcorrectie.
  • Levenshtein Distance - Dit berekent hoeveel toetsaanslagen er nodig zijn om de ene string in de andere te veranderen, bijvoorbeeld om van 'CLC 2200npk' naar 'CLC 2200' te komen is 3, terwijl van 'CLC 2200npk' naar 'CLC 1100' is 5.

Hier is een interessant artikel waarin beide algo's samen worden toegepast, wat u misschien een paar ideeën kan geven.

Nou, hopelijk helpt dat een beetje.

EDIT:Hier is een veel snellere gedeeltelijke Levenshtein Distance-implementatie (lees de post die niet exact dezelfde resultaten oplevert als de normale). Op mijn testtafel van 125000 rijen draait het in 6 seconden vergeleken met 60 seconden voor de eerste waarnaar ik linkte.




  1. Rijdoelen, deel 2:Semi-joins

  2. Wat is de echte waarde van het introduceren van Microsoft Access in uw organisatie?

  3. mySQL converteer varchar naar datum

  4. SELECT max(x) retourneert null; hoe kan ik ervoor zorgen dat het 0 teruggeeft?