AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Ähnlichkeitssuche in einer SQL-Datenbank???
Thema durchsuchen
Ansicht
Themen-Optionen

Ähnlichkeitssuche in einer SQL-Datenbank???

Ein Thema von romber · begonnen am 6. Sep 2005 · letzter Beitrag vom 21. Jun 2006
Antwort Antwort
romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Ähnlichkeitssuche in einer SQL-Datenbank???

  Alt 6. Sep 2005, 00:44
Datenbank: MSSQL Server • Version: 2000 • Zugriff über: ADO
Hallo!

Ich möchte eine Datenbank-Tabelle auf ein Wort durchsuchen, dabei sollen auch ähnliche Treffer angezeigt werden. Ich habe schon mal so etwas gemacht, es war aber normale Strings, die ich mithilfe Levenshtein-Algo vergliechen habe. Sicher gibt es so was in der Art auch für die Datenbanken. Jede korporative Datenbank, die ich bis heute gesehen habe, hatte so was an Bord, muss also möglich sein. Hat jemand schon so was gemacht?
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Ähnlichkeitssuche in einer SQL-Datenbank???

  Alt 6. Sep 2005, 00:54
Ja,

das habe ich mal für MSSQL geschrieben, als Prozedur (mit temporären Tabellen nachgebildet)
Allerdings würde ich dafür jetzt wohl eine eigene Delphi-Library schreiben, diese dann in den Server integrieren. Somit kannst du Delphicode im Server ausführen.

MfG
Thorsten
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: Ähnlichkeitssuche in einer SQL-Datenbank???

  Alt 6. Sep 2005, 01:42
So, habe mich nochmal etwas näher damit beschäftigt.

Nachdem ich oben nur sehr ungenau war möchte ich jetzt etwas genauer werden...

Ich habe mal eine DLL angelegt, die du in den Server integrieren kannst (siehe Anhang).

In der Master-Datenbank unter "Erweiterte gespeicherte Prozeduren" musst du die DLL eintragen. Beim Namen muss angegeben werden: xp_Levenshtein

Mit
SQL-Code:
DECLARE @d INT
EXEC master..xp_Levenshtein 'Text1', 'Text2', @r = @d OUTPUT
SELECT @d
könntest du jetzt schon auf die neue Funktion zugreifen.

Es geht aber auch noch etwas schöner...

In deiner Datenbank unter "Benutzerdefinierte Funktionen" eine neue Funktion anlegen
SQL-Code:
CREATE FUNCTION dbo.Levenshtein (@S1 VARCHAR, @S2 VARCHAR)
RETURNS INT AS
BEGIN
  DECLARE @b INT
  EXEC master..xp_Levenshtein @S1, @S2, @a = @b OUTPUT
  RETURN @b
END
Jetzt ist der Zugriff auf die Funktion auch innerhalb einer SQL-Abfrage möglich.
SQL-Code:
SELECT *, dbo.Levenshtein(feld1, feld2)
FROM tabelle
Hoffe das hilft dir weiter.

MfG
Thorsten
Angehängte Dateien
Dateityp: zip levenshtein_204.zip (222,0 KB, 25x aufgerufen)
  Mit Zitat antworten Zitat
romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#4

Re: Ähnlichkeitssuche in einer SQL-Datenbank???

  Alt 6. Sep 2005, 01:48
@omata

Wow! Danke für deine Mühe! Muss gleich ausprobieren. Vielen Dank!
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#5

Re: Ähnlichkeitssuche in einer SQL-Datenbank???

  Alt 6. Sep 2005, 01:56
Beim MSSQL hast du 2 Möglichkeiten das sauber zu lösen ...

Zum einen gibt es die SOUNDEX Funktion

SQL-Code:
   SELECT Vorname
         ,Name
   FROM Mitarbeiter
   WHERE SONDEX(Name) = SOUNDEX('meiher')
   -- findet Maier, Mayer, Meiner ....
Zum Anderen kannst du dir mit DEFFERENCE() eine Suchfunktion mit "Trefferqualität-Ranking" bauen.
Kleines Beispiel:

SQL-Code:
CREATE PROCEDURE SucheMitarbeiter
 @Vorname Varchar(20),
 @Name Varchar(20)
AS
Begin
  -- Liefert die eine Trefferliste der Mitarbeiter.
  -- Die besten Ergebnisse stehen oben, die ganz schlechten sind rausgefiltert ...

DECLARE @MinimalPunkte INT
  SET @MinRank = 5

  SELECT Vorname
         ,Name
         ,CASE WHEN DIFFERENCE(Vorname,@Vorname) IS NOT NULL
               THEN DIFFERENCE(Vorname,@Vorname)
               ELSE 4
          END
          +
          CASE WHEN DIFFERENCE(Name,@Name) IS NOT NULL
               THEN DIFFERENCE(Name,@Name)
               ELSE 4
          END
          AS [Rank]
  FROM Mitarbeiter
  WHERE ( DIFFERENCE(Vorname,@Vorname) > 2 )
           AND
          ( UPPER( LEFT(Vorname,2) ) = UPPER( LEFT(@Vorname,2) )
          AND
          ( DIFFERENCE(Name,@Name) > 2 )
           AND
          ( UPPER( LEFT(Name,2) ) = UPPER( LEFT(@Name,2) )
          AND
          (
          CASE WHEN DIFFERENCE(Vorname,@Vorname) IS NOT NULL
               THEN DIFFERENCE(Vorname,@Vorname)
               ELSE 4
          END
          +
          CASE WHEN DIFFERENCE(Name,@Name) IS NOT NULL
               THEN DIFFERENCE(Name,@Name)
               ELSE 4
          END
          ) > @MinRank
  
  ORDER BY -- nach Rank sortieren
          CASE WHEN DIFFERENCE(Vorname,@Vorname) IS NOT NULL
               THEN DIFFERENCE(Vorname,@Vorname)
               ELSE 4
          END
          +
          CASE WHEN DIFFERENCE(Name,@Name) IS NOT NULL
               THEN DIFFERENCE(Name,@Name)
               ELSE 4
          END
          DESC

End

Beschreibungen zu den Funktionen findest du schnell über Google "MSDN SQL DIFFERENCE" bzw. "MSDN SQL SOUNDEX"

Mit persönicch gefällt die Variante mit dem Ranking ganz gut. weil Soundex manchmal etwas stur ist ...
Falls du Fragen dazu hast können wir das morgen Abend mal durchsprechen ...

Schöne Grüße,
Jens
  Mit Zitat antworten Zitat
romber

Registriert seit: 15. Apr 2004
Ort: Köln
1.164 Beiträge
 
Delphi 10 Seattle Professional
 
#6

Re: Ähnlichkeitssuche in einer SQL-Datenbank???

  Alt 8. Sep 2005, 16:54
Danke für die Bespiele!
Werde ie mir jetzt genauer anschauen
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: Ähnlichkeitssuche in einer SQL-Datenbank???

  Alt 21. Jun 2006, 19:35
Ich musste heute leider feststellen, dass ich in meiner Funktionsdeklaration einen Fehler gemacht habe. Sie muss so aussehen...

SQL-Code:
CREATE FUNCTION dbo.Levenshtein (@S1 VARCHAR(100), @S2 VARCHAR(100))
RETURNS INT AS
BEGIN
  DECLARE @b INT
  EXEC master..xp_Levenshtein @S1, @S2, @a = @b OUTPUT
  RETURN @b
END
Gruss
Thorsten
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:58 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz