# Bitweise Überprüfung eines Wertes in SQL



## kiem (2. September 2004)

Ich bin ein Neuling und habe folgendes SQL-Problem (benutze SQL, Access 97 ODBC):

Angenommen da sind Firmenmitarbeiter in einer Spalte "Name". Jeder hat ein oder mehrere Hobbys wie Fussball, Tennis, Judo, Radfahren, Joggen etc. Diese Hobbys will ich in einer Spalte "Hobby" folgendermassen als Zahl speichern (in Access 97 habe ich für die Spalte Hobby den Felddatentyp=Zahl und die Feldgrösse="Byte" eingestellt): Ich möchte für jede Sportart ein Bit setzen, Z.B.:

Fussball = 1
Tennis = 2
Judo = 4
Radfahren = 8
Joggen = 16
Wandern = 32
etc.

Das heisst, wenn Mitarbeiter Meier Tennis spielt, erhält er die Zahl 2. Mitarbeiter Müller spielt Tennis und Judo, erhält also die Zahl 6 (2+4) und Mitarbeiter Keller spielt Fussball und Tennis, fährt Rad und joggt, erhält also in der Spalte "Hobby" die Zahl 27 (aus 1+2+8+16).

Wie muss ich nun die SQL-Abfrage in WHERE formulieren, wenn ich z.B. alle Tennisspieler herausfiltern will?

Wenn die Variable "Wert" die Zahl 2 enthält, so liefert mir folgendes SQL-Beispiel im Resultat nur den Mitarbeiter Meier, und ich möchte ja alle Tennisspieler erhalten:

SELECT *
FROM Firmenmitarbeiter
WHERE Hobby = Wert
ORDER by Name ASC

Ich bräuchte eine bitweise Überprüfung der gespeicherten Zahl in "Hobby" mit der Laufzeitvariablen "Wert". Und genau eine solche bitweise Überprüfung suchte ich bisher vergeblich.

Vielen Dank!


----------



## shutdown (2. September 2004)

Wenn du nur nach der Zahl 2 suchst, dann gibt er dir nur die Leute aus, die AUSSCHLIESSLICH Tennis spielen.

Die Anlage deines Punktesystems ist ja sehr schlau gemacht - wäre ich jetzt nicht so schnell draufgekommen 

Du müsstest dann nur dein WHERE von = 2 umändern in WHERE hobby > 1 AND hobby < 4

Dann bekommst du alle die Tennis (und auch Fussball) spielen.

Sollte das Problem eigentlich lösen

cu shutdown


----------



## kiem (3. September 2004)

Vielen Dank!

Das stimmt, doch ich dachte, dass es irgendwie so gehen müsste, was aber leider nicht geht:

WHERE Hobby = Hobby *and* Wert

Sonst lässt sich die Abfrage zur Laufzeit nicht gut bewerkstelligen, denn einmal möchte ich vielleicht wissen, wer alles Fussball spielt, oder ein andermal wer alles wandert und da müssten die Begrenzungen immer angepasst werden.

Gruss kiem


----------



## shutdown (3. September 2004)

machs halt mit 2 Eingabefeldern und 2 Variablen, über die du deine Abfrage abänderst:

Beispiel du möchtest alle, die Fussball, Judo, oder TEnnis machen

Eingabefeld 1: Minimalwert  - Fall Fussball => 1
Eingabefeld 2: Maximalwert - Fall Judo => muss weniger als 8 sein

==> $var1 = 1;
==> $var2 = 8;

WHERE hobby > $var1 AND hobby < $var2

Wenn du jetzt allerdings einzelne Sportarten zusammen rauspicken willst, dann fällt mir im Moment auch nix ein.

Bereiche (den oder das oder die) oder einzelne Abfragen gehen so aber auf jeden Fall

shutdown


----------



## melmager (3. September 2004)

... where hobby & 2 

& ist die Und Function und zwar Bitweise


----------



## kiem (4. September 2004)

Na ja, schön wäre es mit dem Zeichen "*& *", wenn es denn nur funktionieren würde! Aber leider funktioniert es nicht.
kiem


----------



## shutdown (4. September 2004)

also Bereiche und genau ein Hobby kannst du ja mittlerweile über die Formular-Variante abfragen.

Jetzt erweiterst du das Formular einfach noch so, dass er dein Query dahingehend abwandelt, dass du auch einzelne Hobbys zusammen (Nur Judo und Nur Fußball) abfragen kannst.

Der dazugehörige Befehl ist OR ==> WHERE HOBBY = 1 OR Hobby = 4
usw.

shutdown


----------



## ni6htmare (21. September 2011)

Im allgemeinen SQL macht man eine Bitweise-Verknüpfung so:

spaltenname & Integer > 0


Um das mal mit dem hier aufgeführten Beispiel zu zeigen:

hobby & 2 > 0
Es werden alle gefunden, die als Hobby Fußball haben (neben anderen Hobbies)


Getestet hab ich das in einer Postgres-DB. sollte aber Standard-SQL sein und auch in anderen DBs funktionieren. 

Zur Erklärung:
Der &-Operater vergleich zwei Werte (den Wert in der Db und den Vergleichswert) auf Bit-Ebene und liefert als Ergebnis ein true oder false. Da man aber nicht in jeder DB mit boolean-Werten arbeiten kann, wird auf 0(false) bzw. 1(true) geprüft.

Ich hoffe geholfen zu haben


----------

