Menu

SQLite & NULL: IS NULL, COALESCE und IFNULL richtig nutzen

Wie sich SQLite-Operatoren bei NULL verhalten – warum = und <> hier nicht greifen und wann du stattdessen IS NULL, IS NOT NULL, COALESCE oder IFNULL brauchst.

Diese Seite enthält ausführbare Editoren — bearbeiten, ausführen und Ausgabe sofort sehen.

NULL bedeutet „unbekannt"

Jeder andere Wert in SQLite steht für etwas Konkretes – eine Zahl, einen String, ein Blob. NULL ist anders. Es ist ein Platzhalter für einen Wert, der fehlt oder unbekannt ist. Diese eine Idee erklärt jedes seltsame Verhalten, das NULL in Abfragen an den Tag legt.

Legen wir eine kleine Tabelle an, mit der wir experimentieren können:

Zwei Spalten erlauben NULL-Werte. Boris hat keine E-Mail. Cleo hat kein Alter angegeben. Dan hat weder noch. Auf dem Rest der Seite geht es darum, solche Zeilen abzufragen, ohne in die typischen Fallen zu tappen.

= und <> funktionieren nicht mit NULL

Der erste Reflex ist, einfach WHERE email = NULL zu schreiben. Sieht logisch aus – liefert aber nichts zurück:

Null Zeilen — obwohl Boris und Dan offensichtlich keine E-Mail-Adresse haben. Der Grund: Jeder Vergleich mit NULL liefert wieder NULL zurück, nicht true oder false. Die WHERE-Klausel in SQLite behält aber nur Zeilen, bei denen die Bedingung wahr ist — und NULL ist eben nicht wahr. Also fliegt die Zeile raus.

Dieselbe Falle gibt es bei <>:

Eigentlich würde man erwarten, dass alle außer Ada zurückkommen. Stattdessen erscheint nur Cleo. Boris und Dan, deren E-Mail-Adressen NULL sind, fallen unter den Tisch – denn NULL <> 'ada@example.com' ergibt eben wieder NULL und nicht true.

Das ist mit Abstand die häufigste SQL-Falle. Wenn eine Abfrage plötzlich Zeilen verschluckt, mit denen du gerechnet hast, ist meistens eine Spalte mit NULL schuld.

IS NULL und IS NOT NULL richtig einsetzen

Der saubere Weg, in SQLite auf NULL zu prüfen, ist der IS-Operator. Im Gegensatz zu = kommt er mit NULL klar und liefert immer true oder false zurück – niemals NULL selbst:

Die erste Abfrage liefert Boris und Dan zurück, die zweite Ada und Cleo. IS NULL und IS NOT NULL sind genau die beiden Operatoren, mit denen du fragst: „Fehlt dieser Wert?" Setz sie überall dort ein, wo du sonst versucht wärst, = NULL oder <> NULL zu schreiben.

Wenn du „alle außer Ada, inklusive der unbekannten Werte" haben willst, musst du beide Prüfungen explizit kombinieren:

Jetzt tauchen Boris, Cleo und Dan alle auf.

NULL pflanzt sich durch Arithmetik und Verkettung fort

Diese "unbekannt"-Regel gilt nicht nur bei Vergleichen. Sobald irgendeine Operation auf NULL trifft, ist das Ergebnis ebenfalls NULL:

next_year und doubled sind bei Cleo und Dan null. labelled_age übrigens auch – sobald man einen String mit NULL verkettet, kommt wieder NULL raus und eben nicht 'Age: '. Wenn eine Spalte also null sein kann und du am Ende einen brauchbaren Wert haben willst, musst du den Fall explizit abfangen. Genau dafür gibt es die nächsten beiden Funktionen.

IFNULL: Fallback mit zwei Argumenten

IFNULL(a, b) gibt a zurück – außer a ist null, dann kommt b. Das ist der einfachste Weg, um einen NULL-Wert in SQLite durch einen Default-Wert zu ersetzen:

Boris und Dan bekommen (keine E-Mail). Cleo und Dan bekommen 0. Die Daten in der Tabelle ändern sich dabei nicht – IFNULL schreibt lediglich die Ausgabe um.

IFNULL erwartet immer genau zwei Argumente. Wer mehrere Fallbacks hintereinander braucht, greift zu COALESCE.

COALESCE: Der erste Nicht-NULL-Wert gewinnt

COALESCE(a, b, c, ...) geht die Argumente der Reihe nach durch und liefert den ersten zurück, der nicht NULL ist. Damit ist COALESCE quasi die verallgemeinerte Variante von IFNULL – nur eben mit beliebig vielen Fallbacks:

Bei Ada und Cleo wird die E-Mail-Adresse genommen. Bei Boris und Dan ist die E-Mail NULL – also greift SQLite auf das zweite Argument zurück, eine aus dem Namen zusammengebaute Adresse. Wäre diese ebenfalls NULL, würde am Ende 'anonym' herauskommen.

COALESCE ist die portable Variante: Jede größere SQL-Datenbank unterstützt es auf dieselbe Weise. IFNULL ist dagegen eine bequeme Abkürzung in SQLite und MySQL für den Fall mit genau zwei Argumenten. Im Zweifel also lieber COALESCE nehmen – IFNULL nur dann, wenn du wirklich nur zwei Argumente hast und den kürzeren Namen bevorzugst.

NULL ist nicht dasselbe wie ein leerer String

Ein häufiger Stolperstein: Viele behandeln NULL und '' so, als wären sie austauschbar. Sind sie aber nicht.

'' ist ein echter String – er hat eben null Zeichen. NULL dagegen steht für das Fehlen eines Werts. length('') ergibt 0, während length(NULL) selbst wieder NULL ist. Und NULL = NULL liefert nicht 1, sondern NULL – genau deshalb gibt es überhaupt IS NULL.

Wenn eine Spalte sowohl '' als auch NULL enthalten kann, leg dich darauf fest, was bei dir „fehlender Wert" bedeutet, und bleib konsequent dabei. Sonst musst du in jeder Abfrage beide Fälle abdecken – und irgendwann vergisst du einen davon.

NULL bei IN, NOT IN und DISTINCT

Es gibt noch ein paar weitere Stellen, an denen dir NULL in die Quere kommt.

IN mit einer Liste, die NULL enthält, kann zu überraschenden Ergebnissen führen – vor allem in Kombination mit NOT IN:

Eigentlich würde man erwarten, dass alle zurückkommen, deren Alter nicht 25 ist. Stattdessen bekommt man: nichts. SQLite expandiert NOT IN (25, NULL) ungefähr zu age <> 25 AND age <> NULL, und age <> NULL ergibt immer NULL – die Gesamtbedingung wird also nie wahr. Die Lösung: NULL-Werte vor dem Vergleich aus der Liste (oder aus der Spalte) herausfiltern.

DISTINCT hingegen behandelt NULL-Werte beim Entfernen von Duplikaten als gleich:

Du bekommst drei Zeilen zurück: Adas E-Mail, Cleos E-Mail und ein einzelnes NULL (in das Boris und Dan zusammengefasst wurden). Bei GROUP BY und UNION läuft es genauso – beide behandeln NULL-Werte als eine einzige Gruppe, also genau andersherum als =. SQL ist hier nicht immer konsequent, deshalb lohnt es sich zu wissen, auf welcher Seite welcher Operator steht.

Kurze Checkliste

  • Prüfe fehlende Werte mit IS NULL bzw. IS NOT NULL. Niemals mit = NULL.
  • Sobald NULL bei Arithmetik, Verkettung oder Vergleichen mitspielt, ist das Ergebnis wieder NULL.
  • Mit COALESCE(a, b, c, ...) ersetzt du NULL-Werte durch einen Fallback. Für zwei Argumente reicht die Kurzform IFNULL(a, b).
  • Ein leerer String '' ist nicht dasselbe wie NULL. Entscheide dich pro Spalte für eine Variante, um „fehlt" auszudrücken.
  • NOT IN (..., NULL) ist fast immer ein Bug. Filtere NULL-Werte vorher aus der Liste raus.

Weiter geht's: Ergebnisse sortieren

Wenn du Zeilen sauber filtern kannst – inklusive der mit NULL – ist der nächste Schritt, sie in eine sinnvolle Reihenfolge zu bringen. ORDER BY ist das nächste Thema, und auch dieses Schlüsselwort hat eine eigene Meinung dazu, wo NULL-Werte in der sortierten Ausgabe landen.

Häufig gestellte Fragen

Warum funktioniert column = NULL in SQLite nicht?

Weil NULL für „unbekannt" steht – und jeder Vergleich mit einem unbekannten Wert ist selbst unbekannt, also nicht wahr. WHERE col = NULL liefert deshalb null Zeilen zurück, selbst wenn die Spalte tatsächlich NULL enthält. Du musst stattdessen WHERE col IS NULL schreiben. Das Gleiche gilt für <>: hier brauchst du IS NOT NULL.

Wo liegt der Unterschied zwischen IFNULL und COALESCE in SQLite?

IFNULL(a, b) nimmt genau zwei Argumente und gibt a zurück – außer a ist NULL, dann kommt b. COALESCE(a, b, c, ...) akzeptiert beliebig viele Argumente und liefert das erste, das nicht NULL ist. IFNULL ist also die Kurzform für zwei Werte; COALESCE ist der allgemeine Fall und funktioniert zudem in praktisch jeder anderen SQL-Datenbank gleich.

Ist NULL in SQLite dasselbe wie ein leerer String?

Nein. NULL heißt „gar kein Wert", '' ist dagegen ein String der Länge null – also ein ganz konkreter, bekannter Wert. '' IS NULL ergibt 0 (also falsch), und length('') ist 0, während length(NULL) wieder NULL liefert. Wenn eine Spalte beides erlaubt, musst du in deinen Queries entweder beide Fälle abfangen oder dich beim Schreiben auf eine Variante festlegen.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S