Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Textteile miteinander vergleichen

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von IchHH, 21 Juli 2017.

  1. IchHH

    IchHH Datenbank-Guru

    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.
     
  2. ukulele

    ukulele Datenbank-Guru

    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.
     
  3. akretschmer

    akretschmer Datenbank-Guru

    die Performance dürfte grottig sein. In PG würde ich hier PostgreSQL: Documentation: 9.6: pg_trgm empfehlen. Vielleicht gibt es ja Alternativen.
     
  4. IchHH

    IchHH Datenbank-Guru

    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?
     
  5. ukulele

    ukulele Datenbank-Guru

    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)
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden