Binärer Vergleich in SQL

Hi!

Ich brauche mal eure Hilfe beim Erstellen eines SQL-Vergleiches.

Ich habe zwei Datenfelder auf zwei unterschiedlichen Tabellen (Tab_1 und Tab_2), die ich in der Where-Klausel gegeneinander vergleichen soll. Beide Felder können die Werte von 0 bis 3 annehmen.

Ist Tab_1.Feld = 0, kann der Datensatz ignoriert werden, also:

... where Tab\_1.Feld \> 0

Ist Tab_2.Feld = 0, dann muss der Datensatz immer gelesen werden, also:

... and Tab\_2.Feld = 0

Außerdem gelten folgenden Konstellationen:

Wenn Tab_1.Feld = 1
und Tab_2.Feld = 1 --> Datensatz ignorieren

Wenn Tab_1.Feld = 1
und Tab_2.Feld = 2 --> Datensatz lesen

Wenn Tab_1.Feld = 1
und Tab_2.Feld = 3 --> Datensatz ignorieren

Wenn Tab_1.Feld = 2
und Tab_2.Feld = 1 --> Datensatz lesen

Wenn Tab_1.Feld = 2
und Tab_2.Feld = 2 --> Datensatz ignorieren

Wenn Tab_1.Feld = 2
und Tab_2.Feld = 3 --> Datensatz ignorieren

Wenn Tab_1.Feld = 3
und Tab_2.Feld = 1 --> Datensatz lesen

Wenn Tab_1.Feld = 3
und Tab_2.Feld = 2 --> Datensatz lesen

Wenn Tab_1.Feld = 3
und Tab_2.Feld = 3 --> Datensatz ignorieren

Dies brachte mich auf die Idee eines Bitvergleiches. Im den Fällen 1 bis 3 wird als das 1-Bit verglichen, in den Fällen 4 bis 6 das 2-Bit, ind den Fällen 7 bis 9 das 1-Bit und das 2-Bit.

Wie aber bekomme ich das in SQL hin, vor allem so allgemein, dass die o.g. Entscheidungstabelle korrekt umgesetzt wird?

Das SQL müsste irgendwie dann in diese Richtung gehen:

... where Tab\_1.Feld \> 0
and
(Tab\_2.Feld = 0 or ...???)

Danke für jede Idee!

Grüße
Heinrich

Außerdem gelten folgenden Konstellationen:

Wenn Tab_1.Feld = 1
und Tab_2.Feld = 2 --> Datensatz lesen

Wenn Tab_1.Feld = 2
und Tab_2.Feld = 1 --> Datensatz lesen

Wenn Tab_1.Feld = 3
und Tab_2.Feld = 1 --> Datensatz lesen

Wenn Tab_1.Feld = 3
und Tab_2.Feld = 2 --> Datensatz lesen

Das SQL müsste irgendwie dann in diese Richtung gehen:

… where Tab_1.Feld > 0
and
(Tab_2.Feld = 0 or …???)

Danke für jede Idee!

Grüße
Heinrich

Wo ist das Problem? Du hast noch 4 Konstellationen, die du in die WHERE-Klausel einsetzen musst, jetzt brauchst du nur noch die Klammern, die AND’s und die OR’s richtig zu setzen. Oder habe ich da etwas missverstanden.

Hi!

Das Problem ist zwischenzeitlich gelöst.

Die Where-Bedingung sieht jetzt so aus:

... where 
Tab\_1.Feld \> 0
and 
Tab\_1.Feld & Tab\_2.Feld Tab\_1.Feld

Grüße
Heinrich

Hallo Heinrich,

du schreibst leider nicht, welches DBMS Du einsetzt - anhand deiner Lösung würde ich aber mal sagen Oracle ist es nicht :wink:.

Einen Hinweis wollte ich aber jedenfalls noch anbringen: Wenn komplexere WHERE Klauseln öfter in Abfragen anfallen und diese Klausel dann auch noch hinreichend selektiv ist sowie auch noch deterministisch ist (also nur von Tabellendaten und nicht z.B. von der Uhrzeit abhängt), dann sollte man zumindest mal einen Gedanken an die Auslagerung in eine Funktion verschwenden.

Ich hätte also (vielleicht) in dem Fall einmal eine Funktion geschrieben, die dir 1 für die korrekten Sätze zurückliefert und NULL für alle anderen. Dann noch flugs einen Function-Based-Index über die Funktion, einen View, der das Ganze kapselt und schon hast du die mit ziemlicher Sicherheit fixeste Variante, wie du diese Abfrage durchführen kannst - hat natürlich nur dann einen Sinn wenn

  • die Tabelle einigermaßen viele Sätze enthält
  • die Funktion nicht für soviele Sätze 1 liefert, dass ein Full Table Scan schon wieder flotter ist
  • du das Ganze nicht gerade nur einmal brauchst

Gruß
Martin