Bulanık dize işlevleriyle yaklaşık eşleşmeleri bulma

Tamamlandı

Gerçek dünya verileri nadiren mükemmel bir şekilde eşleşir. Müşteri adları yanlış yazılabilir, adresler farklı kısaltılabilir veya tutarsız olarak girilen ürün açıklamaları olabilir. Benzer dize eşleştirme işlevleri, benzer ama aynı olmayan kayıtları bulmanıza yardımcı olarak veri kalitesi iyileştirmeleri, yinelenen algılama ve daha esnek arama özellikleri sağlar.

Dize benzerliği kavramlarını anlama

Benzer eşleşen algoritmalar, aralarındaki farkları hesaplayarak iki dizenin ne kadar benzer olduğunu ölçer. İki birincil yaklaşım yaygın olarak kullanılır:

Uzaklığı düzenle (Levenshtein uzaklığı), bir dizeyi diğerine dönüştürmek için gereken en az tek karakterli işlem sayısını (eklemeler, silmeler, değiştirmeler) sayar. Düşük değerler daha benzer dizeleri gösterir.

Benzerlik puanları , dizeler arasındaki ilişkiyi yüzde veya oran olarak ifade eder; burada yüksek değerler daha büyük benzerlik gösterir.

Şu örnekleri göz önünde bulundurun:

  • "renk" → "renk": düzenleme mesafesi = 1 (bir 'u' ekleyin)
  • "veritabanı" → "veritabaes": düzenleme mesafesi = 2 ('e' ve 's' değerlerini değiştir)
  • "Microsoft" → "Microsft": edit distance = 1 (delete 'o')

Uyarı

Benzer eşleşme, tam eşleştirmeye kıyasla hesaplama açısından pahalıdır. Genellikle diğer ölçütler kullanılarak önceden filtrelenmiş aday kümelerinde stratejik olarak kullanın.

Düzenleme mesafesini EDIT_DISTANCE ile hesaplayın

işlevi iki EDIT_DISTANCE dize arasındaki Levenshtein mesafesini döndürür. Bu, bir dizeyi diğerine dönüştürmek için gereken en az düzenleme sayısıdır. Amaç, tanımlı bir eşiğe göre benzer dizeleri bulmaktır.

Aşağıdaki örnekte nasıl kullanılacağı EDIT_DISTANCEgösterilmektedir:

SELECT 
    EDIT_DISTANCE('color', 'colour') AS ColorVariant,     -- Returns 1
    EDIT_DISTANCE('database', 'databaes') AS Typo,        -- Returns 2
    EDIT_DISTANCE('SQL Server', 'SQL Server') AS Exact,   -- Returns 0
    EDIT_DISTANCE('hello', 'world') AS Different;         -- Returns 4

Küçük çeşitlemelere rağmen yinelenen veya eşleşen kayıtları bulmak için kullanabilirsiniz EDIT_DISTANCE :

-- Find customers with similar names to a search term
DECLARE @searchName NVARCHAR(100) = 'Jon Smith';

SELECT 
    CustomerID,
    FirstName,
    LastName,
    FirstName + ' ' + LastName AS FullName,
    EDIT_DISTANCE(@searchName, FirstName + ' ' + LastName) AS EditDistance
FROM SalesLT.Customer
WHERE EDIT_DISTANCE(@searchName, FirstName + ' ' + LastName) <= 3
ORDER BY EDIT_DISTANCE(@searchName, FirstName + ' ' + LastName);

Ayrıca, olası yinelenen ürünleri de bulabilirsiniz:

-- Find product pairs with similar names
SELECT 
    p1.ProductID AS Product1ID,
    p1.Name AS Product1Name,
    p2.ProductID AS Product2ID,
    p2.Name AS Product2Name,
    EDIT_DISTANCE(p1.Name, p2.Name) AS EditDistance
FROM SalesLT.Product AS p1
INNER JOIN SalesLT.Product AS p2
    ON p1.ProductID < p2.ProductID
WHERE EDIT_DISTANCE(p1.Name, p2.Name) <= 5
ORDER BY EDIT_DISTANCE(p1.Name, p2.Name);

Tavsiye

Anlamlı düzenleme uzaklığı üst sınırı dize uzunluğuna bağlıdır. Kısa dizeler için (5-10 karakter), 1-2 düzenleme uzaklığı benzerliği gösterir. Daha uzun dizeler için 3-5 arası mesafe değerlerine izin verebilirsiniz.

Benzerliği ölç EDIT_DISTANCE_SIMILARITY

EDIT_DISTANCE_SIMILARITY 0 ile 100 arasında normalleştirilmiş bir benzerlik puanı döndürür; burada 100 aynı dizeleri temsil eder. Bu yüzde tabanlı ölçümün yorumlanması, özellikle farklı uzunluktaki dizeleri karşılaştırırken ham düzenleme uzaklığından daha kolaydır:

SELECT 
    EDIT_DISTANCE_SIMILARITY('color', 'colour') AS ColorSimilarity,     -- ~85
    EDIT_DISTANCE_SIMILARITY('database', 'databaes') AS TypoSimilarity, -- ~75
    EDIT_DISTANCE_SIMILARITY('SQL', 'SQL Server') AS PartialMatch,      -- ~30
    EDIT_DISTANCE_SIMILARITY('hello', 'hello') AS Exact;                -- 100

Aşağıdaki örnekte olduğu gibi eşik ile yaklaşık eşleşmeleri bulmak için benzerlik puanlarını kullanabilirsiniz:

-- Find products similar to a search term (at least 70% similar)
DECLARE @searchTerm NVARCHAR(100) = 'Mountain Bike Frame';

SELECT 
    ProductID,
    Name,
    EDIT_DISTANCE_SIMILARITY(@searchTerm, Name) AS SimilarityScore
FROM SalesLT.Product
WHERE EDIT_DISTANCE_SIMILARITY(@searchTerm, Name) >= 70
ORDER BY EDIT_DISTANCE_SIMILARITY(@searchTerm, Name) DESC;

ile fonetik benzerlik hesaplama JARO_WINKLER_DISTANCE

Jaro-Winkler algoritması özellikle adları ve kısa dizeleri karşılaştırmak için tasarlanmıştır. En baştan eşleşen dizelere daha yüksek puanlar vererek ön eklerin daha önemli olduğu kişi adları için özellikle etkili olmasını sağlar:

SELECT 
    JARO_WINKLER_DISTANCE('MARTHA', 'MARHTA') AS NameTypo,      -- ~0.96
    JARO_WINKLER_DISTANCE('JONES', 'JOHNSON') AS SimilarNames,  -- ~0.83
    JARO_WINKLER_DISTANCE('JOHN', 'JON') AS NameVariant,        -- ~0.93
    JARO_WINKLER_DISTANCE('SMITH', 'SMYTH') AS SpellingVar;     -- ~0.96

Jaro-Winkler puanı 0 ile 1 arasında değişir; burada 1 aynı dizeleri gösterir. 0,9'un üzerindeki bir puan genellikle isimlerde güçlü bir eşleşme olduğunu ifade eder.

Aşağıdaki örnek, arama girişine benzer adlara sahip müşterileri bulur:

-- Find customers with names similar to a search
DECLARE @searchFirst NVARCHAR(50) = 'John';
DECLARE @searchLast NVARCHAR(50) = 'Smythe';

SELECT 
    CustomerID,
    FirstName,
    LastName,
    JARO_WINKLER_DISTANCE(@searchFirst, FirstName) AS FirstNameScore,
    JARO_WINKLER_DISTANCE(@searchLast, LastName) AS LastNameScore,
    (JARO_WINKLER_DISTANCE(@searchFirst, FirstName) + 
     JARO_WINKLER_DISTANCE(@searchLast, LastName)) / 2 AS CombinedScore
FROM SalesLT.Customer
WHERE JARO_WINKLER_DISTANCE(@searchFirst, FirstName) > 0.85
  AND JARO_WINKLER_DISTANCE(@searchLast, LastName) > 0.85
ORDER BY CombinedScore DESC;

Uyarı

Jaro-Winkler, adlar gibi kısa dizeler için iyileştirilmiştir. Adresler veya açıklamalar gibi daha uzun dizeler EDIT_DISTANCE_SIMILARITY için genellikle daha iyi sonuçlar sağlar.

Performansla ilgili dikkat edilmesi gerekenler

Benzer eşleştirme işlevleri her iki dizedeki her karakteri inceleyerek hesaplama açısından yoğun olmalarını sağlar. Tam dizge karşılaştırması, karakterler farklılık gösterdiğinde durdurulabilir ve dizine alınan aramalar verimli B-ağacı dolaşımı kullanır. Buna karşılık, bulanık algoritmaların benzerlik puanlarını karakter bazında hesaplaması gerekir. Bir milyon satır içeren bir tablo için iyileştirilmemiş benzer arama, her biri onlarca karakter karşılaştırması içeren bir milyon benzerlik hesaplaması gerçekleştirebilir.

Benzer eşleştirmenin verimli olması için önemli olan, pahalı benzer işlevleri uygulamadan önce aday kümesini azaltmaktır. Önce sonuçları daraltmak için desenleri LIKE , ilgili alanlardaki tam eşleşmeleri veya aralık filtrelerini içeren dizine alınan sütunları kullanın. Sadece o zaman daha küçük aday kümesine bulanık eşleştirme uygulanmalıdır.

Aşağıdaki örneklerde bu aşamalı filtreleme yaklaşımı gösterilmektedir:

-- Not good: Fuzzy match against entire table
SELECT * FROM LargeCustomerTable
WHERE EDIT_DISTANCE_SIMILARITY('John Smith', FullName) > 70;

-- Better: Pre-filter before fuzzy matching
SELECT * FROM LargeCustomerTable
WHERE FullName LIKE 'J%'  -- First letter filter
  AND EDIT_DISTANCE_SIMILARITY('John Smith', FullName) > 70;

-- Best: Use multiple pre-filters
SELECT * FROM LargeCustomerTable
WHERE FirstName LIKE 'Jo%'
  AND LastName LIKE 'Sm%'
  AND JARO_WINKLER_DISTANCE('John', FirstName) > 0.85
  AND JARO_WINKLER_DISTANCE('Smith', LastName) > 0.85;

Önemli

, EDIT_DISTANCEve EDIT_DISTANCE_SIMILARITY gibi JARO_WINKLER_DISTANCEbenzer dize eşleştirme işlevleri SQL Server 2025 ve sonraki sürümlerde, Azure SQL Veritabanı'nda ve Microsoft Fabric'teki SQL veritabanlarında kullanılabilir. Belirli özellik kullanılabilirliği için platformunuzun belgelerine bakın.

Benzer dize eşleştirme hakkında daha fazla bilgi için bkz. Dize İşlevleri.