Zurück zur Artikelliste Artikel
5 Leseminuten

Verstehen der Verwendung von NULL in der dreiwertigen Logik von SQL

NULLs sind in relationalen Datenbanken notwendig, und der Umgang mit ihnen ist für den Erfolg von SQL von grundlegender Bedeutung. Allerdings sollten NULLs auch mit Vorsicht behandelt werden, wie wir in diesem Beitrag erklären.

In relationalen Datenbanken haben wir nicht immer einen Wert, den wir in eine Spalte setzen können. Nehmen wir zum Beispiel an, wir haben eine Tabelle namens "Personen" mit den Spalten "Vorname", "Nachname", "Geburtsdatum" und "Heiratsdatum". Welchen Wert speichern wir in der Spalte "Heiratsdatum" für einzelne Personen? In diesem Fall könnte die Spalte keinen Wert haben, da Alleinstehende nicht verheiratet sind. Wir brauchen eine Möglichkeit, um anzuzeigen, dass wir keinen Wert für diese Spalte haben. Glücklicherweise gibt es eine solche Möglichkeit: den NULL-Wert, der in relationalen Datenbanken weit verbreitet ist.

NULLs können auf jeden Datentyp angewendet werden: Ganzzahlen, Datumsangaben, VARCHARs oder jeden anderen Spaltentyp. Aber wir müssen vorsichtig sein, wenn wir Berechnungen oder Ausdrücke erstellen, die einen oder mehrere Operatoren mit einem NULL-Wert enthalten. Sehen wir uns an, warum.

NULLs und dreistufige Logik

Der Grund dafür, dass NULLs manchmal für Verwirrung sorgen können, hat mit der sogenannten dreiwertigen Logik zu tun. Während die binäre oder boolesche Logik zwei Werte hat ("wahr" und "falsch"), hat die dreiwertige Logik (abgekürzt als 3VL und auch als ternäre Logik bekannt) einen zusätzlichen Wert - "unbekannt".

Lassen Sie uns 3VL anhand eines einfachen Szenarios veranschaulichen. Nehmen wir an, wir möchten die Namen der Mitarbeiter ermitteln, die mehr als 1.200 € im Monat verdienen. Die Tabelle employee Tabelle sieht wie folgt aus:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1000 NULL

Wir versuchen die folgende Abfrage:

SELECT * FROM employee WHERE bonus + salary > 1200;

Das Ergebnis ist:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500

Wir sollten drei Datensätze in der Ergebnismenge sehen, aber es sind nur zwei. Warum ist Peter White nicht enthalten? Der Grund dafür ist der NULL-Wert in der Spalte bonus. In SQL gibt jede arithmetische Operation, die einen Operanden mit einem NULL-Wert enthält, ein NULL-Ergebnis zurück.

Sehen Sie sich also an, wie der Datensatz von Peter White ausgewertet wurde:

1800 + NULL > 1200

Mit anderen Worten, Peters Gehalt (1.800) und seine Prämie (NULL) ergaben zusammen NULL. Wir können diese Bedingung auf reduzieren:

NULL > 1200

Ist NULL also größer als 1.200? Denken Sie daran, dass NULL einen nicht existierenden Wert darstellt, was bedeutet, dass wir nichts haben, was wir mit 1.200 vergleichen können: Wir können nicht wissen, ob diese Aussage wahr oder falsch ist. So funktioniert die dreiwertige Logik. Wenn wir einen NULL-Wert in einer Bedingung haben, wird das Ergebnis dieser Bedingung "unbekannt" sein.

3VL in SQL-Abfragen in den Griff bekommen

Um zu verstehen, wie die dreiwertige Logik funktioniert, gehen wir den Prozess Schritt für Schritt durch. Überlegen Sie zunächst, wie die Datensätze in der WHERE-Klausel gefiltert werden. Nur Datensätze, die in der WHERE-Klausel als "wahr" bewertet werden, gehören zur Ergebnismenge der Abfrage. Datensätze, die als "falsch" oder "unbekannt" bewertet werden, sind nicht Teil des Ergebnisses. Aus diesem Grund wurde der Datensatz von Peter White in den vorherigen Abfrageergebnissen nicht berücksichtigt. Sein Gesamtgehalt wird in der WHERE-Klausel mit "Unbekannt" bewertet; "1800 + NULL > 1200" ist "Unbekannt", weil wir nicht wissen können, was NULL ist.

AND-, OR- und NOT-Tabellen sind in der dreiwertigen Logik ebenfalls wichtig, daher werden wir sie einzeln betrachten und sehen, wie sie berechnet werden. Beginnen wir mit der NOT-Tabelle:

Value NOT Result
True False
False True
Unknown Unknown

Als nächstes sehen wir uns die AND-Tabelle an:

AND True False Unknown
True True False Unknown
False False False False
Unknown Unknown False Unknown

Analysieren wir, warum "falsch" UND "unbekannt" gleich "falsch" ist. Ein "falsch" reicht aus, um bei einer UND-Verknüpfung das gesamte Ergebnis "falsch" zu machen. Dies gilt unabhängig davon, ob der zweite Wert "wahr", "falsch" oder "unbekannt" ist.

Schließlich haben wir noch die OR-Tabelle:

OR True False Unknown
True True True True
False True False Unknown
Unknown True Unknown Unknown

Versuchen wir eine Abfrage, die den OR-Operator verwendet:

SELECT * FROM employee WHERE salary < 1500 OR bonus > 200 

Das Ergebnis ist das folgende:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500
Nick Perry 1000 NULL

Beachten Sie, dass ein Datensatz, der einen NULL-Wert in der Spalte "Bonus" enthält, im Ergebnis angezeigt wird, der andere NULL-Datensatz jedoch nicht. Der Grund dafür ist der OR-Operator. Da die Bedingung Gehalt < 1500 wahr ist, ist es nicht notwendig, die Bedingung Bonus > 200 auszuwerten.

Umgang mit der unbekannten Variable

Manchmal können Sie die Verwendung "unbekannter" Werte in WHERE-Bedingungen vermeiden, indem Sie NULL-Werte mit der Funktion COALESCE() in andere Werte (wie 0) umwandeln. Betrachten Sie die vorherigen Beispiele. Wenn Sie jeden NULL-Wert in "0" umwandeln würden, bevor der Wert in WHERE verglichen wird, würden Sie andere Ergebnisse als die oben gezeigten erhalten. Diese Konvertierung kann jedoch je nach der Semantik der Abfrage möglich sein oder nicht. Versuchen wir es trotzdem und sehen wir, was passiert.

SELECT * FROM employee WHERE coalesce(bonus,0) > 200 OR salary < 1500

Die Abfrage wird nur "wahre" oder "falsche" Ergebnisse liefern. In diesem Fall wird die zweiwertige Logik angewendet.

Nehmen wir an, wir erhalten den Auftrag, den Mitarbeitern, die weniger als 1.600 € im Monat verdienen, eine Gehaltserhöhung von 5 % zu gewähren. Wie sollten wir diese Abfrage formulieren? Versuchen wir es mal:

UPDATE employee
SET salary = salary *1.05
WHERE salary + bonus <= 1600

Hier sind die Ergebnisse:

First Name Last Name Salary Bonus
John Smith 1050 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1000 NULL

Moment mal - das Gehalt von Nick hat sich nicht geändert! Das ist nicht fair! Wieder verursacht das "unbekannte" Ergebnis der Bedingung "Gehalt + Bonus <= 1600" für Nicks Datensatz ein Problem.

Unser zweiter Versuch ist besser:

UPDATE employee
SET salary = salary *1.05
WHERE salary + coalesce(bonus,0) <= 1600

Wie wir im folgenden Abfrageergebnis sehen können, wurde das Gehalt beider Datensätze (John und Nick) geändert.

First Name Last Name Salary Bonus
John Smith 1050 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1050 NULL

Probieren Sie es selbst aus!

Es kann viele verschiedene WHERE-Klauseln geben, die als "unbekannt" oder "falsch" ausgewertet werden. Probieren Sie doch einmal selbst einige SQL-Abfragen aus und sehen Sie, welche Werte "wahr", "falsch" oder "unbekannt" sind. LearnSQL.de können Sie alles über die WHERE-Klausel und ihre Bedingungen lernen. Probieren Sie es kostenlos aus!