Verketten mit Liste in Where Bedingung

IchHH

Datenbank-Guru
Beiträge
282
Hallo,

eigentlich wollte ich eine vermeindlich einfache Where Bedingung schreiben.

Gedacht hatte ich mir sowas wie:

Code:
Where Emailadresse Not Like '%@%.' + ('ac',
'ad',
'ae',
'aero',
'af',
'ag',
'ai',
'al',
'am')

An was habe ich nicht gedacht?

Danke für eure Hilfe.
 
Werbung:
Hallo Chucky,

das verstehe ich, leider ist die Liste mit den Endungen nicht vollständig, insgesamt sind es 268. Und wenn ich mit 268 Or Bedingung arbeite, dann ist die Geschwindigkeit der Abfrage unterirdisch.

Noch eine Idee?
 
Zumindest MSSQL kennt diese Syntax nicht. Bei NOT LIKE wäre es allerdings mit AND statt OR zu verknüpfen.

Eine Werteliste kannst du nur mit IN Ablgeichen, das ist leider mit LIKE nicht zu kombinieren. Du könntest den String aus der Spalte vorher zerlegen und das Ergebnis dann mit IN abgleichen, Beispiel:
Code:
WHERE Emailadresse NOT LIKE '%@%.%' AND right(Emailadresse,charindex('.',reverse(Emailadresse))-1) NOT IN ( 'werteliste' )
 
Achso wenn du natürlich charindex auf "." nutzt muss der natürlich auch vorhanden sein sonst gibts ne Fehlermeldung von der DB wenn nur eine Zeile gar keinen Punkt hat. Das müsstest du sinnvoll abfangen, sonst kommt da 0 raus und du versuchst mit right() -1 Zeichen auszugeben, das knallt.
Code:
WHERE Emailadresse NOT LIKE '%@%.%'
OR Emailadresse LIKE '%.%'
AND right(Emailadresse,charindex('.',reverse(Emailadresse))-1) NOT IN ( 'werteliste' )
 
Kann M$SQL funktionale Indexe? Damit könnte man das beschleunigen noch. Demo mit PostgreSQL und regexp_replace() statt right(...(charindex...(reverse)))

Code:
test=*# select * from mail;
         mail         
----------------------
 someone@irgendwo.de
 someone@irgendwo.ac
 someone@irgendwo.ad
 someone@irgendwo.ae
 someone@irgendwo.af
 someone@irgendwo.ai
 someone@irgend.wo.ai
 someone@irgend.wo.de
(8 Zeilen)
test=*# create index idx_mail on mail (mail) where (regexp_replace(mail,'^.*\.','')) <> all ('{ac,ad,ae,ai,af}'::text[]);
CREATE INDEX
test=*# explain analyse select * from mail where regexp_replace(mail,'^.*\.','') not in ('ac','ad','ae','ai','af');
                                                      QUERY PLAN                                                     
----------------------------------------------------------------------------------------------------------------------
 Index Only Scan using idx_mail on mail  (cost=0.13..12.19 rows=3 width=32) (actual time=0.024..0.025 rows=2 loops=1)
   Heap Fetches: 2
 Planning time: 0.212 ms
 Execution time: 0.036 ms
(4 Zeilen)

test=*# select * from mail where regexp_replace(mail,'^.*\.','') not in ('ac','ad','ae','ai','af');
         mail         
----------------------
 someone@irgend.wo.de
 someone@irgendwo.de
(2 Zeilen)

test=*#

Allerdings enthält die Index-Definition auch diese komplette Liste der Werte, sollte sich die ändern, müßte auch der Indexneu erstellt werden.
 
Werbung:
Gut möglich, ich habe bei mir aus Vereinfachungsgründen tatsächlich tld, Domain, Host etc als Spalten in der Tabelle und befülle sie per Trigger. Ist redundant aber wen kümmert schon Speicherplatz.
 
Zurück
Oben