LIKE-Abfrage über alle Felder

Hallo SQLer :wink:

Ich habe heute mal eine Frage zum Aufbau eines SQL-Strings, der mir meine Arbeit in einigen Fälle erleichtern soll. Ich erkläre mein Anliegen mal an einem Beispiel:

Es geht um eine Tabelle namens „AdressenTab“, in der persönliche Kontaktdaten gespeichert sind. Sagen wir mal in den Feldern: Vorname, Name, Strasse, Plz, Ort, Telefon, eMail

In einer Suchmaske soll nun diese Tabelle (und zwar alle Felder) nach einem beliebigen Suchstring durchsucht werden. Normalerweise würde ich hierfür einen SQL-String wie diesen verwenden:

SELECT \* FROM AdressenTab WHERE Vorname like 'Suchbegriff' OR Name like 'Suchbegriff' OR Strasse like 'Suchbegriff' OR ... ;

Da dies bei größeren Tabellen jedoch recht zeit- und nervenraubend ist, würde ich eine Variante wie diese bevorzugen:

SELECT \* FROM AdressenTab WHERE AdressenTab.\* like 'Suchbegriff';

Leider funktioniert das bei mir (Access97-2000) so nicht. Gibt es überhaupt eine Möglichkeit, alle Felder einer Tabelle zu durchsuchen, ohne auf meine o.g. umständliche Methode zurückgreifen zu müssen???

Grüße und schonmal Danke an alle, die sich hierüber Gedanken machen und mir ein wenig weiterhelfen können…

(Woly)

Hi,

In einer Suchmaske soll nun diese Tabelle (und zwar
alle Felder) nach einem beliebigen Suchstring
durchsucht werden.

Hier meine beliebte Standardantwort zu diesem Thema: Überdenke das.
Normalerweise macht das keinen Sinn, entweder nach Herrn Meyer oder nach der Meyerstraße zu suchen. Die Aufteilung in Feldern mit inhaltlicher Definition ist sinnvoll; sonst könnte man alles in einer Spalte speichern und sich die Tabellendefinition vereinfachen :smile:

:SELECT \* FROM AdressenTab WHERE Vorname like


> 'Suchbegriff' OR Name like 'Suchbegriff' OR Strasse like  
> 'Suchbegriff' OR ... ;

Da dies bei größeren Tabellen jedoch recht zeit- und
nervenraubend ist, würde ich eine Variante wie diese
bevorzugen:

:SELECT \* FROM AdressenTab WHERE AdressenTab.\* like


> 'Suchbegriff';

Das geht nicht.
Du hast zwei Möglichkeiten: einmal, das SQL-Statement dynamisch zu erzeugen aus der Tabellendefinition (siehe Collection Datenbank.Tabledefs).
Dies ist zunächst mal aufwendiger, Du kannst das aber in eine Funktion packen, die das für jede beliebige Tabelle tut. Der Nachteil: Dieses like „Begriff“ or like … ist sehr langsam.
Eine ander Methode wäre, die Spalten zu konkatenieren und dann zu vergleichen, also:

WHERE spalte1 & spalte2 & ... & spalten-1 & spalten 
 LIKE "%Begrigff%"


    
    Auch dieses könntest Du in einer Funktion dynamisch bauen lassen.
    
    Gruß
    
    J.

Hallo Jose,

die Adressdatenbank diente hier lediglich als einfaches Beispiel für mein Problem. Tatsächlich möchte ich das in einer Tabelle anwenden, bei der die Suche in allen Feldern auch wirklich einen Sinn macht. Dein Hinweis ist natürlich völlig korrekt.

Auf jeden Fall schonmal vielen Dank für Deine Vor- und Ratschläge; das ein oder andere werd ich mit Sicherheit verwenden können.

Gruß
(Woly)

hi!

(da misch ich mich gleich als angehender access-experte ein :wink:

ev. könnte das problem mit einem „union [all]“ gelöst werden … es geht zwar ein _bißchen_ schneller, jedoch weltanschauungsändernd ist es auch nicht …

select x from y where a like ‚%suchstring%‘
union
select x from y where b like ‚%suchstring%‘
union …

eine weiter möglichkeit würde in einer view bestehen …

der performance-killer bleibt aber das „like“ …

grüße,
tomh

Hi,

select x from y where a like ‚%suchstring%‘
union
select x from y where b like ‚%suchstring%‘
union …

Stimmt, machbar ist es.
Aber auch als Oracle-Experte wird Dir doch klar sein, daß Unions DER Performancekiller schlechthin sind…
Gruß

J.

hi!

Hi,

select x from y where a like ‚%suchstring%‘
union
select x from y where b like ‚%suchstring%‘
union …

Stimmt, machbar ist es.
Aber auch als Oracle-Experte wird Dir doch klar sein, daß
Unions DER Performancekiller schlechthin sind…

ok, dann mit „union all“ … jedoch auf die frage, ob ein or oder ein union langsamer sei, würde ich zumindest kein generelles ja oder nein als antwort geben …

(lustig wird’s dann, wenn noch zusätzlich minus etc. dabei sind :wink:

grüße,
tomh

ok, dann mit „union all“ … jedoch auf die frage, ob ein or
oder ein union langsamer sei, würde ich zumindest kein
generelles ja oder nein als antwort geben …

Hallo Tomh,

ich mag mich ja irren, aber muss bei einem UNION nicht mindestens zweimal auf die Tabelle zugegriffen werden ? Und ist dies beim OR nicht unnötig ? Und ist ein Tabellenzugriff nicht immer besser als zwei Tabellenzugriffe ?

Gruß Janus

Ein View wäre hier eine konkrete Lösung:

SELECT id, f1 || f2 || f3…

Hier werden alle Felder (ausser der Table-ID bzw. dem PK) zu einem Feld zusammengefasst, worauf ein einziger LIKE genügt.

~stefan

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi,

Ein View wäre hier eine konkrete Lösung:

SELECT id, f1 || f2 || f3…

Hier werden alle Felder (ausser der Table-ID bzw. dem PK) zu
einem Feld zusammengefasst, worauf ein einziger LIKE genügt.

Ähm… meine Antwort oben enthält genau diesen Vorschlag:

WHERE spalte1 & spalte2 & … & spalten-1 & spalten LIKE „%Begrigff%“

(Und zwar formuliert für Access, worauf sich die Frage bezog)

Gruß

J.

hi janus!

Hallo Tomh,

ich mag mich ja irren, aber muss bei einem UNION nicht
mindestens zweimal auf die Tabelle zugegriffen werden ? Und
ist dies beim OR nicht unnötig ? Und ist ein Tabellenzugriff
nicht immer besser als zwei Tabellenzugriffe ?

Gruß Janus

du irrst dich nicht, wobei jedoch beim einzelnen select des unions der vorteil besteht, daß das kaskadische (stimmt das so?) produkt wesentlich kleiner ist als beim or … dazu kommt noch, daß indizes beim or mit vorsicht zu genießen sind (wobei beim like kann man indizes sowieso vergessen), wobei beim union man direkt auf den index zugreifen kann … ich hab schon drei- viermal das union all dem or vorgezogen, da es wesentlich performanter war - der umgekehrte fall tritt jedoch genauso auf … es kommt immer auf den einzelnen fall drauf an, und da checkt man halt mittels tkprof oder toad, wo der performance-killer ist und probiert dann herum …

eigentlich wollte ich nur darauf hinweisen, daß ein union diesen fall ebenfalls abbildet und es gar nicht mal langsamer als das or sein muß …

grüße,
tomh

kaskadische (stimmt das so?)

Kartesisches Produkt. :smile:

Grüße, Robert

Hallo Tomh,

(wobei beim like kann man indizes sowieso vergessen

schon klar, was du meinst. So ist es aber falsch.

SELECT *
FROM emp
WHERE ename LIKE ‚S%‘;

kann durchaus über einen Index laufen. Ausnahme : Der Index ist als Reverse-Key-Index definiert.

Aber nochmal zum eigentlichen Thema:
Ich habe gerade bei OR-Abfragen sehr gute Erfahrungen mit Bitmap-Indexes gemacht. Ein UNION war in diesen Fällen immer langsamer. Leider macht dieser Index-Typ aus verschiedenen Gründen nicht immer Sinn (siehe auch : http://www.dbazine.com/jlewis3.html )

Gruß Janus

kaskadische (stimmt das so?)

Kartesisches Produkt. :smile:

Grüße, Robert

danke! (f* fremdwörter :wink: … dachte mir schon, daß das „cascade“ damit nix zu tun haben kann …

grüße,
tomh