Operatoren für Sql-Abfragen (TSql)

In Sql-Abfragen können Ausdrücke durch verknüpfende Operatoren zu neuen Ausdrücken zusammengefügt werden. Zwei Ausdrücke lassen sich durch Vergleichsoperatoren miteinander vergleichen, so daß ein Wahrheitswert zurückgegeben wird. So erzeugte Wahrheitswerte können mit logischen Operatoren zu neuen Wahrheitswerten verbunden werden.

1. Verknüpfende Operatoren

1.1 Unäre Operatoren

Unäre Operatoren werden direkt vor numerischen Ausdrücken notiert und erzeugen einen neuen Ausdruck:

+Positiv: gibt den Wert des nachfolgenden Ausdrucks als positiven Wert zurück
-Negativ: gibt den Wert des nachfolgenden Ausdrucks als negativen Wert zurück
~Bitweises NOT: gibt den Wert der nachfolgenden Ganzzahl so zurück, daß jedes Bit umgedreht wird: 0 wird zu 1 und 1 wird zu 0.

1.2 Arithmetische Operatoren

Arithmetische Operatoren umfassen die Standard-Rechenoperationen und werden immer zwischen zwei numerischen Ausdrücken notiert:

+Addition: A_Preis + 10.0
-Subtraktion: A_Preis - 10.0
*Multiplikation: A.A_Preis * U.A_Stueck
/Division: Monatsumsatz / 20.0
%Modulo: gibt den ganzzahligen Rest einer Division zurück:
23 % 5 = 3, da 23 = 4*5 + 3 ist

1.3 Verknüpfung von Zeichenketten

Mit '+' können, zusätzlich zur Addition zweier Zahlen, zwei Zeichenketten miteinander verknüpft werden:

Select P.Nachname + ', ' + P.Vorname From Personen As P

Zu beachten ist, daß bei uneindeutigen Verknüpfungen zwischen einer Zeichenkette und einer Zahl versucht wird, die Zeichenkette in eine Zahl zu konvertieren. Gelingt dies, so wird '+' als arithmetischer Operator interpretiert. Ist die Zeichenkette nicht konvertierbar, wird ein Laufzeitfehler erzeugt.

5 + '9'erzeugt 14
'5' + 9erzeugt ebenfalls 14, die Position der Zahl ist irrelevant
'5' + '9'erzeugt den String '59'
'5.3' + 9dies scheitert, da '5.3' nicht als Integer interpretierbar ist
'5.3' + 9.0erzeugt 14.3, da nun versucht wird, '5.3' als Dezimalzahl zu interpretieren
'5,3' + 9scheitert mit Hinweis auf eine fehlgeschlagene Konvertierung, da in der englischen Standardeinstellung der Punkt und nicht das Komma das Dezimaltrennzeichen ist

1.4 Bitweise Operatoren

Die drei Bit-Operatoren &, | und ^ (And, Or, XOr) erzeugen aus zwei Ganzzahlen eine neue Ganzzahl, indem in beiden Ausdrücken Bits mit derselben Position miteinander verglichen werden, um das Ergebnisbit festzulegen. Das Gesamtergebnis ist gleich der Zahl, die sich aus der Kombination der Einzelbits ergibt. Hierbei gilt die folgende Verknüpfungstabelle:

erster Ausdruckzweiter Ausdruck&|^
00000
10011
01011
11110

& und | verhalten sich wie ihre logischen Äquivalente, ^ / XOr liefert genau dann 1, falls die beiden Bits verschieden sind. Eine Integer-Zahl > 0, bei welcher nur das n-te Bit gesetzt ist, ist gleich 2^(n - 1), so daß die Folge der gesetzten Bits den Zahlen 1, 2, 4, 8 ... entspricht. Für die Verwendung von Bitwerten empfielt es sich, sämtliche Zahlen in Zweierpotenzen zu zerlegen. Für Ausdrücke in Ausgabespalten ergeben sich hieraus bsp. die folgenden Werte:

AusdruckWert
1 | 23
1 & 20
1 ^ 23
5 | 913
5 & 91
5 ^ 912
1363 | 86339723
1363 & 8633273
1363 ^ 86339450

Innerhalb von server-daten können Bitvergleiche einerseits direkt für alle Integer-Spalten genutzt werden, andererseits steht mit dem bitSet-Datentyp, der intern als Integer implementiert ist, eine codierte Nutzungsmöglichkeit zur Verfügung. Wird dieser Datentyp in der Where-Klausel einer benutzerdefinierten Abfragen verwendet, so müssen die Bitoperatoren genutzt werden, da der Gleichheitsoperator hier fehlerhaft sein kann. Enthält eine Bittabelle die Werte 1, 2, 4 und 8, so sind die Werte 0 - 15 (= 1+2+4+8) interpretierbare Werte in einer Detailspalte 'myBit' mit Relation auf diese Bittabelle. Die folgende Tabelle verdeutlicht, wie in einem Where-Abschnitt eine solche Spalte verwendet werden kann.

Where-BedingungErläuterung
(myBit & 10) = 10prüft, ob in myBit sowohl 2 als auch 8 gesetzt ist
(myBit & 10) <> 0prüft, ob in myBit 2 oder 8 (oder beide) gesetzt ist
(myBit & 10) = 0prüft, ob in myBit weder 2 noch 8 gesetzt ist

2. Vergleichsoperatoren und die dreiwertige SQL-92-Logik

Ein einfacher Vergleichsoperator wird immer zwischen zwei Ausdrücke notiert. Er prüft, ob die beiden Ausdrücke in jenem Verhältnis zueinander stehen, welches durch diesen Operator beschrieben wird und gibt in diesem Fall 'True' zurück. Stehen die beiden Ausdrücke nicht in dem durch den Operator beschriebenen Verhältnis, so wird 'False' zurückgegeben. Ein erweiterter Vergleichsoperator nutzt eine spezielle, vom Operator abhängige Syntax. Er verhält sich in bezug auf die Verarbeitung wie ein einfacher Operator und gibt True oder False zurück.

Sind einer oder beide Ausdrücke Null, so ist das Ergebnis davon abhängig, ob das DBMS das Standard-SQL-92-Verhalten implementiert. Wird dieser Standard berücksichtigt, dann wird jeder Vergleich mit mindestens einem Null-Ausdruck zu Null ausgewertet, auch die Verneinung von Null oder der Vergleich 'Null = Null' ergibt Null. Das SQL-92-Verhalten wird innerhalb des MS-SqlServers mittels der Set ANSI_NULLS on|off-Option an- bzw. ausgeschaltet. Bei ausgeschalteter Option ((@@options & 32) = 0) wird 'Null = Null' oder 'Null != 1' zu True ausgewertet. Innerhalb von server-daten ist diese Option immer gesetzt, die ausgeschaltete Option wird hier nicht weiter diskutiert.

2.1 Einfache Vergleichsoperatoren

=Gleichheit
<kleiner als
>größer als
<=kleiner oder gleich
>=größer oder gleich
<>verschieden
!=nicht gleich *
!<nicht kleiner *
!>nicht größer *

Die drei mit '*' markierten Operatoren gehören nicht zum Sql-92-Standard.

2.2 Erweiterte Vergleichsoperatoren

Bei erweiterten Vergleichsoperatoren handelt es sich um Operatoren mit einer jeweils individuellen Syntax. Ansonsten können sie wie einfache Vergleichsoperatoren verwendet werden und geben analog True, False oder Null zurück.

Between<erster Ausdruck> Between <zweiter Ausdruck> And <dritter Ausdruck>

prüft, ob der erste Ausdruck zwischen dem zweiten und dem dritten Ausdruck liegt

5 Between 3 And 7 ergibt True

In<erster Ausdruck> In (<kommagetrennte Liste von Ausdrücken> | <Unterabfrage>)

prüft, ob der erste Ausdruck gleich einem der Werte in der Aufzählung oder gleich einem der von der Unterabfrage zurückgelieferten Werte ist

5 In (3, 5, 7) ergibt True

Like<erster Zeichenfolgen-Ausdruck> Like <zweiter Zeichenfolgen-Ausdruck>

prüft, ob der erste Ausdruck dem Muster des zweiten Ausdrucks entspricht. Dieses kann Platzhalter (%, _) und Gruppenzeichen ([, ]) enthalten.

ExistsExists (<Unterabfrage>)

liefert True zurück, falls die Unterabfrage mindestens einen Wert zurückliefert. Die Unterabfrage wird hierbei mit einer impliziten Top 1 - Klausel ausgeführt und beendet, sobald eine Zeile gefunden wurde. Für positive Prüfungen ist dies erheblich schneller als bsp. ein Count(*) > 0 - Vergleich.

All | [Any | Some]<erster Ausdruck> <Standard-Vergleichsoperator> All|[Any|Some] (<Unterabfrage>)

Der erste Ausdruck wird bezüglich des Standard-Vergleichsoperators auf jeden Wert geprüft, der von der Unterabfrage zurückgegeben wird. Wird 'All' verwendet, so muß die Prüfung für alle Werte aus der Unterabfrage erfolgreich sein. Wird 'Any' (Synonym: Some) verwendet, so ist die Prüfung dann erfolgreich, falls eine Einzelprüfung positiv ist.

In allen Fällen, in welchen eine Unterabfrage verwendet werden kann, muß diese eine Spalte zurückliefern.

2.3 Die dreiwertige SQL-92-Logik

Im Vergleich zu anderen Programmiersprachen handhabt SQL Vergleiche in zweifacher Hinsicht anders. Zum einen kann ein Vergleich nur innerhalb einer Where-Bedingung (Select/Update/Delete) oder eines When-Abschnittes innerhalb einer komplexen Case-Anweisung genutzt werden. Es ist nicht möglich, den Wahrheitswert als Ergebnis eines Vergleichs direkt auszugeben, ihn in eine Zelle abzulegen oder einen Wahrheitswert ohne Operator in einer Where-Bedingung zu verwenden. Die folgenden Befehle werden deshalb beim Kompilieren verworfen:

Select (0 = 0) As WahrTest, (0 = 1) As FalschTest [From Tabelle]
Select 1 Where True
Update Tabelle Set Ergebniszelle = (@Notendurchschnitt < Klausurergebnis)

In VB.NET oder anderen Programmiersprachen sind die analogen Anweisungen problemlos verwendbar:

i_ersterWert = 5
i_zweiterWert = 3
bool_Variable = (i_ersterWert < i_zweiterWert)    'bool_Variable hat nun den Wert <False>

Es können jedoch verschiedene bzw. verschieden viele Werte in Abhängigkeit von einer Where-Bedingung zurückgegeben werden:

Select 1 Where (0 = 1)gibt keine Zeile zurück
Select 1 Where (0 = 0)gibt genau eine Zelle mit dem Wert 1 zurück
Select * From <Tabelle> Where Exists (Select 1 Where @Var1 = @Var2)ist die Bedingung erfüllt, so gibt die Unterabfrage eine Zeile zurück, 'Exists' liefert True, also werden alle Zeilen von <Tabelle> zurückgegeben
Select Case When (@Var1 = @Var2) Then 1 Else 0 Endgibt immer eine Zelle zurück, der Wert ist 1 oder 0

Zum anderen werden Ausdrücke mit Null immer zu Null ausgewertet. Dies gilt auch für die Negation mit 'Not'. Zeilen, welche in einer Where-Bedingung zu Null ausgewertet werden, fehlen im Ergebnis. Damit kennt die Logik drei Werte - True, False und Null. Für die Auswertung einer ganzen Tabelle genügt es deshalb nicht, einen Operator und dessen Verneinung zu nutzen, sondern es müssen zusätzlich die Werte behandelt werden, welche mit 'Is Null' True erzeugen. Man betrachte eine einspaltige Tabelle mit drei Zeilen und Werten 3, 5 und Null ({3, 5, Null}). Dann gilt:

CodeErgebnis
Select Eintrag From Tabelle Where Eintrag = 3{3}
Select Eintrag From Tabelle Where Not (Eintrag = 3){5}
Select Eintrag From Tabelle Where Eintrag != 3{5}
Select Eintrag From Tabelle Where Not (Eintrag != 3){3}
Select Eintrag From Tabelle Where Not (Eintrag <> 3){3}
Select Eintrag From Tabelle Where Eintrag Is Null{Null}
Select Eintrag From Tabelle Where Eintrag Is Null
Union
Select Eintrag From Tabelle Where Eintrag Is Not Null
{3, 5, Null}

3. Logische Operatoren

Ein logischer Operator negiert entweder den Wert eines einzelnen Vergleichs (Not) oder verknüpft zwei Vergleiche miteinander (And, Or). Hierbei gilt die folgende Wahrheitstabelle:

erster
Boolean-Ausdruck
zweiter
Boolean-Ausdruck
AndOr
TrueTrueTrueTrue
TrueFalseFalseTrue
FalseTrueFalseTrue
FalseFalseFalseFalse

'And' liefert immer False, außer falls beide Einzelausdrücke wahr sind. 'Or' gibt immer True zurück, falls nicht beide Ausdrücke falsch sind. Für 'Or' kann damit auch ein boolscher Einzelausdruck zu Null ausgewertet werden. So gibt die folgende Anweisung 1 zurück:

Select 1 Where (Null = 1) Or (2 = 2)

4. Rangfolge der Operatoren

Werden in einem komplexen Ausdruck mehrere Operatoren verwendet, so wird die Reihenfolge der Auswertung durch den Rang der Operatoren gemäß der folgenden Liste festgelegt. Die unitären Operatoren der ersten Zeile sind die am stärksten bindenden Operatoren.
  • unitäre Operatoren +, -, ~ (bitweises NOT)
  • * (Multiplikation), / (Division), % (Modulo)
  • + (Addition zweier Zahlen), + (Verketten von Zeichenfolgen), - (Subtraktion), & (bitweises And)
  • =, >, <, >=, <=, <>, !=, !>, !< (Vergleichsoperatoren)
  • ^ (bitweises XOr), | (bitweises Or)
  • Not
  • And
  • All, Any/Some, Between, In, Like, Or
  • = (als Zuweisungsoperator, nicht in server-daten verfügbar)
Folgen zwei Operatoren, die hier in einer Zeile stehen, unmittelbar aufeinander, so wird der im Ausdruck links stehende Operator zuerst ausgewertet. Deshalb gilt:

5 % 2 * 3 = (5 % 2) * 3 = 1 * 3 = 3
5 & 1 + 1 = (5 & 1) + 1 = 1 + 1 = 2
8 ^ 4 | 15 = (8 ^ 4) | 15 = 12 | 15 = 15

Eine explizite Rechtsklammerung erzeugt dagegen für jede Zeile andere Ergebnisse:

5 % (2 * 3) = 5 % 6 = 5
5 & (1 + 1) = 5 & 2 = 0
8 ^ (4 | 15) = 8 ^ 15 = 7

Es wird empfohlen, großzügig Klammern zu setzen, um spätere Fehlinterpretationen bei der Überarbeitung von Code zu vermeiden.


Kontaktformular:

Schreiben Sie mir und wir bauen gemeinsam Ihre neue Web-Datenbank!

Die Erläuterungen zum Datenschutz habe ich gelesen und stimme diesen zu.

© 2003-2019 Jürgen Auer, Berlin.