2009-04-24 9 views
2

Ich versuche, so etwas wiemehr wie auf derselben Spalte DB2

select emp_id from dept.employee where 
    firstname like '%sam%' or 
    firstname like '%SAM%' or 
    firstname like '%will%' or 
    firstname like '%WILL%' 

abfragen Ist es möglich, es wie

in regex etwas zu setzen
select emp_id from dept.employee where 
    firstname like '%sam|SAM|will|WILL%' 

oder

select emp_id from dept.employee where 
    upper(firstname) like '%sam%' or 
    upper(firstname) like '%will%' 

Ich bin Verwenden von DB2 UDB9.

Antwort

0

Das ist entweder ein schlechtes Beispiel oder ein schlechtes Datenbank-Design :-).

Sie sollten wahrscheinlich nicht erste (oder irgendwelche) Namen in irgendeiner Weise speichern, die Sie benötigen, um LIKE zu verwenden. Sie müssen daran denken, dass Tabellen sind fast immer immer lesen viel öfter als geschrieben, und dementsprechend zu entwerfen.

Das bedeutet, Sie möchten, dass die Kosten beim Einfügen oder Aktualisieren liegen, nicht bei der Auswahl. Pro-Zeile-Funktionen wie upper(name) skalieren nie gut zu den richtigen Datenbanken der Enterprise-Klasse.

Meiner Meinung nach, sollten Sie haben, für DB2, die folgenden:

  • ein insert/update-Trigger, der führende und nachgestellte Leerzeichen aus dem ersten (und letzten) Name wird entfernen.
  • eine generierte Spalte, die die Namen in Großbuchstaben umwandelt (dies benötigt mehr Speicher, aber das ist normalerweise besser als Zeitverschwendung). Ich bin mir nicht sicher, ob UDB9 Spalten erzeugt hat (DB2/z hat), aber Sie können dies im selben Einfüge-/Aktualisierungstrigger tun. Grundsätzlich ist es eine zusätzliche Spalte, die immer auf die Großbuchstabe eines anderen Feldes eingestellt ist.
  • ein Index für die generierte Spalte, nicht die ursprüngliche Spalte.

Auf diese Weise Ihr wählt mit Abfragen wie (groß und hässlich, aber effizient) schreien zusammen:

select * from tbl 
where generatedname = 'SAM' 
or generatedname = 'SAMUEL' 
or generatedname = 'SAMANTHA' 
or generatedname = 'WILL' 
or generatedname = 'WILLIAM' 
or generatedname = 'WILLOMENA' 

oder (weniger groß und hässlich, genauso effizient, und näher an der ursprünglichen Abfrage in der Absicht):

select * from tbl 
where generatedname like 'SAM%' 
or generatedname like 'WILL%' 

die volle Leistung des Abfrageoptimierer verwenden (DB2 und andere DBMS‘würde ich denken, kann immer noch optimiert‚% XX‘leicht, wenn das Feld indiziert ist).

Ich bin kein großer Fan von LIKE für jede anständige Größe Tabellen, obwohl manchmal nicht viel Auswahl. Ich kann mir keine brauchbare Situation vorstellen, in der Sie nach "%SAM%" suchen würden, und dies führt dazu, dass der Optimierer nicht in vollem Umfang verwendet werden kann.

+0

das war ein schlechtes Beispiel dies ist für ein weniger abgefragt Feld mehr Beschreibung wie Feld für einen Datensatz. – pmu

Verwandte Themen