Seite 1 von 1

Suche nach Substring....

Verfasst: Do, 13. Dez 2018 17:57
von satmax
Ich habe eine DB wo die Telefonnummern in verschiedensten Formaten gespeichert sind:
+55 (555) 555555
055 5555 5555 -55
0055 55555/5555 (55)

Ich bekomme nun einen Anrufer via TAPI rein 0055555555555 und soll nun den entsprechenden Eintrag in der DB finden. Ideen?

Gibt es eine Art Stringremove in SQL damit ich alle nicht nummerischen Zeichen entfernen kann?

Re: Suche nach Substring....

Verfasst: Do, 13. Dez 2018 18:11
von satmax
Wobei das grundsätzlich funktioniert:

Code: Alles auswählen

select Telefon from Adressen
where replace(Replace(replace(replace(replace(TELEFON,' ',''),'(',''),')',''),'-',''),'/','')  like'%5555555%'
Aber ist halt nicht gerade super leserlich....

Re: Suche nach Substring....

Verfasst: Do, 13. Dez 2018 18:15
von nightcrawler
Du musst Dir eine Funktion schreiben, welche die Telefonnummern normalisiert und die Normalisierung vergleichen. Am Schnellsten geht es, wenn die normalisierten Telefonnummern gespeichert sind und Du nur den Suchbegriff bei der Abfrage normalisieren musst.

Re: Suche nach Substring....

Verfasst: Fr, 14. Dez 2018 7:50
von satmax
Normal ja, aber ich habe nur lesenden Zugriff auf diese DB. Also muss ich mich mit den vorhandenen Daten arrangieren...

Re: Suche nach Substring....

Verfasst: Fr, 14. Dez 2018 21:51
von ramses
Wieviele Datensätze hat die Datenbank denn?

Bei Postgres gäbe es die REGEXP_REPLACE() Funktion zu Suche.....
Aber richtig schnell ist dies nicht, die Nummern in der Datenbank für die Suche normalisieren wäre der beste Weg ....
Du hast ja nicht nur das "nicht ZIffer" Problem sondern auch noch das + zu 00 Problem ....

Gruss Carlo

Re: Suche nach Substring....

Verfasst: Sa, 15. Dez 2018 0:53
von AUGE_OHR
hi,
satmax hat geschrieben: Do, 13. Dez 2018 17:57 Gibt es eine Art Stringremove in SQL damit ich alle nicht nummerischen Zeichen entfernen kann?
Antwort ist jetzt nicht SQL sondern xBase (alle Versionen)

bei Rufnummer würde ich die letzten 4 Stellen als Zahlenfolge für den Such-String nehmen und mit OrdwildSeek() in einen "vorbereiteten" Index suchen.

angenommen ein Feld Type "C",10

1.) alles was keine Zahl ist gehört nicht in den Index
2.) der IndexKey muss, wie das Feld, die selbe Länge (hier 10) haben

Code: Alles auswählen

FUNCTION TNR2STR( value )
LOCAL cRet := ""
LOCAL nLen := LEN( value )
LOCAL i, nDiff
LOCAL cStr

   FOR i = 1 TO nLen
      cStr := SUBSTR( value, i, 1 )
// ad 1.)
      IF !EMPTY(VAL(cStr)) .or. cStr = "0"
         cRet += cStr 
      ENDIF
   NEXT   

// ad 2.)
   nDiff := nLen - LEN( cRet )
   FOR i = 1 TO nDiff
      cRet += CHR( 32 )
   NEXT

RETURN cRet
das mache ich nun mit allen Rufnummer Feldern

Code: Alles auswählen

      _tagname = "ALLETELNO"                                
      _keyfeld = "TNR2STR(VORTELE)+" + ;
              "TNR2STR(TELGES) +" + ;
              "TNR2STR(VORFAX) +" + ;
              "TNR2STR(TELFAX) +" + ;
              "TNR2STR(VORPRIV)+" + ;
              "TNR2STR(TELPRI) +" + ;
              "TNR2STR(HANDY1) +" + ;
              "TNR2STR(HANDY2) +" + ;
              "TNR2STR(ANHANDY)+" + ;
              "TNR2STR(PVVORT1)+" + ;
              "TNR2STR(PVTEL1) +" + ;
              "TNR2STR(PVVORF1)+" + ;
              "TNR2STR(PVFAX1) +" + ;
              "TNR2STR(PVHANDY)"

      ORDCREATE( _cdxname, _tagname, _keyfeld )
      CLOSE INDEX
wie schon gesagt reichen meisten die letzten 4 Stellen der Rufnummer aus.
wenn es mehrere Treffer sind kann man auf 5 Stellen erweitern und innerhalb der Treffer weiter suchen

Re: Suche nach Substring....

Verfasst: Mo, 20. Dez 2021 10:57
von dtmackenzie
Ich benutze folgende Funktion in unserer Postgres-Datenbank um Telefonnummern zu normalisieren:

Code: Alles auswählen

CREATE OR REPLACE FUNCTION public.tel_normalize(
	telstr text)
    RETURNS text
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE PARALLEL UNSAFE
AS $BODY$

DECLARE
    ts text := trim(telstr);
    is_plus boolean := (left(ts, 1) = '+');
BEGIN
    ts := regexp_replace(ts, '[^0-9]+', '', 'g');   -- Retain only digits
    IF is_plus THEN
        RETURN ts;
    END IF;
    IF left(ts, 2) = '00' THEN
        RETURN substr(ts, 3);
    END IF;
    IF left(ts, 1) = '0' THEN
        RETURN '49' || substr(ts, 2);
    END IF;
    RETURN '49341' || ts;
END;
$BODY$;
Der Fall RETURN '49341'... ist spezifisch zu Leipzig (Nummer ohne Vorwahl).