Textteile miteinander vergleichen

IchHH

Datenbank-Guru
Beiträge
284
Hallo,

ich mal wieder mit einer Frage. Kann man nicht festgelegte Bereiche einer Zelle auslesen und mit einer anderen Tabelle vergleichen?

Ich möchte in zwei Datenbanken die über die PLZ miteinander verbunden sind. Alle "richtig" geschriebenen Straßennamen haben. Dazu wollte ich das mindestens 3 Zeichen der fehlerhaften Tabelle dazu beitragen den richtigen Namen aus der Adresstabelle zu finden, damit ich nicht zuviele Vorschläge habe. Da der Anfangsbuche alle zuviele möglichkeiten eröffnet versuche ich eben den Weg über 3 zusammenhängende Zeichen ein Match zu finden.
 
Werbung:
Geht alles, könnte allerdings ordentlich auf die Performance gehen wenn man das mit zuvielen Datensätzen oder zu langen Zeichenketten macht.
Code:
WITH strassenverzeichnis(id,plz,strasse) AS (
   SELECT 1,'01234','Hauptsraße' UNION ALL
   SELECT 2,'01234','Mautsraße' UNION ALL
   SELECT 3,'01234','Wattuweg'
   ), stammdaten(id,plz,strasse) AS (
   SELECT 1,'01234','auptstraße 23'
   ), v(id,plz,strasse,string) AS (
   SELECT   id,
       plz,
       right(strasse,len(strasse)-1),
       left(strasse,3)
   FROM   strassenverzeichnis
   UNION ALL
   SELECT   id,
       plz,
       right(strasse,len(strasse)-1),
       left(strasse,3)
   FROM   v
   WHERE   len(strasse) >= 3
   ), s(id,plz,strasse,string) AS (
   SELECT   id,
       plz,
       right(strasse,len(strasse)-1),
       left(strasse,3)
   FROM   stammdaten
   UNION ALL
   SELECT   id,
       plz,
       right(strasse,len(strasse)-1),
       left(strasse,3)
   FROM   s
   WHERE   len(strasse) >= 3
   ), t(s_id,v_id,anzahl) AS (
   SELECT   s.id,
       v.id,
       count(*)
   FROM   s
   INNER JOIN v
   ON     s.plz = v.plz
   AND     s.string = v.string
   GROUP BY s.id,v.id
   )
SELECT   stammdaten.id,
     stammdaten.plz,
     stammdaten.strasse,
     strassenverzeichnis.strasse,
     100/(len(stammdaten.strasse)-2)*t.anzahl AS quote
FROM   t
INNER JOIN stammdaten
ON     stammdaten.id = t.s_id
INNER JOIN strassenverzeichnis
ON     strassenverzeichnis.id = t.v_id
ORDER BY stammdaten.id,5 DESC
Hier ein Beispiel. Ich habe eine Tabelle strassenverzeichnis in dem stehen alle richtigen Straßennamen mit PLZ. In stammdaten habe ich einen Datensatz dessen Straßenname nicht existiert.

Ich zerlege jetzt in den Tabellen v und s die Zeichenketten der Spalte strasse in 3-Zeichenblöcke, eine Zeichenkette wie "strasse" ergibt fünf Zeilen mit "str", "tra", "ras", "ass" und "sse". Dann joine ich in der Tabelle t Zeichenblöcke zusammen und zähle die Übereinstimmungen damit ich im Anschluss sowas wie eine Trefferquote habe.

Das ist noch nicht perfekt weil natürlich wiederkehrende Begriffe im Namen (z.B. Straße, Weg, Allee) die Quote verändern.
 
Ehrlich?! Ich habe keinen von euch beiden Verstanden. Das mit den Zerlegen erscheint mir ja noch für Sinnvoll auch wenn, bedingt durch Straße, Allee usw, mehr Datensätze generiert werden. Wie aber soll mir das Ergebnis weiterhelfen die richtige Adresse zu ermitteln. Im Moment erledige ich alles über Where left(Straßenname,6) = left(Straße,6) was soweit auch gut funktioniert. Aber je kleiner die Zahl ist desto mehr vorschläge erhalte ich natürlich für eine Adresse. Mit LTRIM und RTRIM zu arbeiten macht kein Sinn da bereits in den ausgesuchten Text fehler enthalten sein könnten bzw. in der "richtigen" Tabelle die Zeichenfolge vielleicht nicht an der selben stelle komm, da abgekürzt wurde usw. Nun könnte man die obige Idee jedoch mit meiner verbinden. Kann man nicht "zählen" lassen wieviel Zeichen in beiden Tabellen identisch sind und dann nur die jenige wählen die die höchste Zahl hat?
 
Werbung:
Mein Code ist von der vorgehensweise recht ähnlich wie die PG Funktion, aber natürlich nicht besonders optimiert. Du kannst den Code nehmen und dir angucken wie die einzelnen Teile funktionieren, ich hab es ja nicht nur in Text beschrieben.

Nur über left() und right() Strings im WHERE-Teil vergleichen wird zu keinem adequaten Ergebnis führen. Vielleicht hilft dir Jaro-Winkler Similarity, Levenshtein Distance oder die MSSQL DIFFERENCE-Funktion weiter.
[MS SQL] Compare text strings for similarity • r/SQL
BI: Beer Intelligence? · Finding Similar Strings With Fuzzy Logic Functions Built Into MDS
DIFFERENCE (Transact-SQL)
 
Zurück
Oben