Einträge mit Null in der DB
droom
- datenbank
Ich habe folgendes Problem. In der DB, habe ich einige Einträge mit dem Wert NULL. Wenn ich nun meine SQL Query so stelle:
select car from Cars where stand !='gebraucht';
werden die Autos, die kein stand (NULL) haben gar nicht angezeigt. Wieso das denn? wie kann ich das lösen?
Hi,
werden die Autos, die kein stand (NULL) haben gar nicht angezeigt. Wieso das denn? wie kann ich das lösen?
der Grund dafür ist, dass per SQL-Definition folgende Regel gilt: Jeglicher Vergleich mit NULL wird nicht zu true oder false sondern zu NULL evaluiert, WHERE erlaubt aber nur die Zeilen, die zu TRUE evaluiert wurden.
In deinem Fall:
SELECT car FROM cars WHERE stand != 'gebraucht' OR stand IS NULL
MfG
Rouven
danke schön Rouven. Wah hilfereich. ;-)
yo,
Jeglicher Vergleich mit NULL wird nicht zu true oder false sondern zu NULL evaluiert
ein vergleich kennt nur falls oder true, insofern wird der vergleich durch NULL schon false.
Ilja
Hi,
da widerspreche ich, es sei denn ich habe gerade bei der Beispielkonstruktion einen Fehler gemacht - Hab meine DB2 gerade nicht hier, daher muss ein SQL-Server 2005-Express herhalten.
Angelegt wurde eine Tabelle mit einer Spalte title, in der bei einem Datensatz ein Wert steht, beim anderen steht NULL drin.
SELECT *
FROM table
WHERE title = NULL
liefert nach deiner Logik nichts, weil der Vergleich title=NULL zu false evaluiert.
OK, kehren wir das um, wenn ich also ein NOT darauf anwende müsste ich den entsprechenden Satz bekommen:
SELECT *
FROM table
WHERE NOT (title = NULL)
-> ergibt immer noch 0 Datensätze.
Wie begründest du das dann? NOT(FALSE) = FALSE?
Meiner Meinung nach ist (title=NULL) -> NULL -> NOT(NULL) -> NULL
Oder siehst du das anders? Hab ich einen Fehler drin?
MfG
Rouven
Achso, und ich hätte hier auch noch einen entsprechenden Blog-Eintrag.
...und einen Artikel
...und das RedHat-Database-SQL-Manual
-> Essenz: NULL-Werte basieren auf einer 3-wertigen Logik von TRUE, FALSE und UNKNOWN, wobei UNKNOWN und NULL mal in die eine, mal in die andere Richtung gleichbedeutend implementiert werden.
Oracle legt sehr viel Wert auf den kleinen Unterschied und widerspricht mir insofern, als dass das Ergebnis eines Vergleiches mit NULL entsprechend dem gerade gesagten nicht NULL sondern UNKNOWN ist.
MfG
Rouven
yo,
Oracle legt sehr viel Wert auf den kleinen Unterschied und widerspricht mir insofern, als dass das Ergebnis eines Vergleiches mit NULL entsprechend dem gerade gesagten nicht NULL sondern UNKNOWN ist.
das hat auch seinen guten grund. was das ausgeben in einem select betrifft, so können NULL werte durchaus "angezeigt" werden. in der WHERE klausel gibt es aber einen unterschied, da es hier um die selektion von datensätzen geht. ich habe halt nur zwei möglichkeiten, den datensatz anzuzeigen oder nicht. da kann man soviel mit NULL und dreiwertigkeit begründen wie man will, letztlich hat man eine reine zweiwertigkeit, nämlich entweder ich zeige den datensatz an oder nicht. und da gibt es dann keinen raum mehr für NULL.
Ilja
Hi Ilja,
[...]nämlich entweder ich zeige den datensatz an oder nicht. und da gibt es dann keinen raum mehr für NULL.
wobei ich genau diesen Punkt anders sehe. Die Erkenntnis, dass ein Datensatz nicht zur Ergebnismenge gehört basiert lediglich auf der Erkenntnis, dass er auf die WHERE-Klausel nicht mit TRUE geantwortet hat; das heißt aber nicht, dass der Vergleich zu false ausgewertet wurde, er kann eben auch unknown sein.
Ich fand übrigens besonders hübsch das Beispiel aus einer der verlinkten Seiten, ob man denn nun zwei Nullwerte vergleichen kann (wenn beide Leute als Geburtsdatum NULL eingetragen haben, haben sie dann am gleichen Tag Geburtstag?). Da NULL kein Wert ist, ist das Ergebnis des Vergleiches NULL=NULL eben NICHT true, sondern NULL (oder wenn man so will UNKNOWN).
MfG
Rouven
yo,
[...]nämlich entweder ich zeige den datensatz an oder nicht. und da gibt es dann keinen raum mehr für NULL.
wobei ich genau diesen Punkt anders sehe.
was gibt es denn noch zwischen einen datensatz anzeigen und nicht anzeigen ?
Ilja
was gibt es denn noch zwischen einen datensatz anzeigen und nicht anzeigen ?
dazwischen gibt es auf - Achtung Schlagwort - Makroebene keinen Unterschied. Aber hinter den Kulissen kann man hinterfragen warum ein Datensatz nicht angezeigt wird, genau das Beispiel mit dem ich eingestiegen bin. Wenn es daran läge, dass alle nicht gelisteten Datensätze die WHERE-Klausel per FALSE verlassen haben, dann müsste man sie mit genau der invertierten Klausel ermitteln können. Genau das geht aber nicht, weil es auf die NULL-Sätze nicht zutrifft -> denn, es gibt zwei Gründe nicht TRUE zu sein, FALSE ist nur einer davon, das ist der, den ich per Negation wieder erwische.
MfG
Rouven
yo,
dazwischen gibt es auf - Achtung Schlagwort - Makroebene keinen Unterschied.
und das ist dann auch schon das entscheidene, mit dem man arbeiten kann.
Aber hinter den Kulissen kann man hinterfragen warum ein Datensatz nicht angezeigt wird
kann man machen, muss man aber nicht. die gründe, die sicherlich sehr vielseitig und unterschiedlich sein können, sind letztlich egal. was unter dem strich bleibt ist eine zweier logik.
Ilja
Moin!
[...]nämlich entweder ich zeige den datensatz an oder nicht. und da gibt es dann keinen raum mehr für NULL.
wobei ich genau diesen Punkt anders sehe.was gibt es denn noch zwischen einen datensatz anzeigen und nicht anzeigen ?
Wenn ich mit einem SQL-Query einen Datensatz NICHT anzeigen kann, und mit der exakt gegenteilig formulierten Bedingung den Datensatz EBENFALLS NICHT anzeigen kann, dann interessiert diese Dreiwertigkeit in der Evaluation der Bedingung schon ziemlich. NULL-Werte sind gesondert zu behandeln - das ist die Essenz.
- Sven Rautenberg
Hi !
select car from Cars where stand !='gebraucht';
Ich schätze mal, die Datenbank holt alle Datensätze bei denen in der Spalte "stand" der Inhalt != 'gebraucht' ist. Wenn also die Spalte keinen Inhalt hat, also null ist, dann wird der Datensatz auch nicht angezeigt.
werden die Autos, die kein stand (NULL) haben gar nicht angezeigt. Wieso das denn? wie kann ich das lösen?
select car from Cars where stand !='gebraucht' or stand is null;
Gruß
Hans