droom: Einträge mit Null in der DB

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?

  1. 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

    --
    -------------------
    Let Bygones Be Bygones  --  Robert Pitscottie: "Chronicles of Scotland"
    1. danke schön Rouven. Wah hilfereich. ;-)

    2. 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

      1. 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

        --
        -------------------
        Death is nature's way of telling you to slow down.
        1. 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

          --
          -------------------
          He is entertaining both out of the car and in the car because if you tell him that a corner is almost flat then he is the guy who is going to try to take it flat even if it means shunting it the other side of it, he will come with the data and say 'hey, I may have crashed and destroyed the car, but I was flat-out'. That is an interesting quality that he has!  --  Team Member on Jacques Villeneuve
          1. 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

            1. 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

              --
              -------------------
              He is entertaining both out of the car and in the car because if you tell him that a corner is almost flat then he is the guy who is going to try to take it flat even if it means shunting it the other side of it, he will come with the data and say 'hey, I may have crashed and destroyed the car, but I was flat-out'. That is an interesting quality that he has!  --  Team Member on Jacques Villeneuve
              1. 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

                1. 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

                  --
                  -------------------
                  "I wish it need not have happened in my time" - "So do I, and so do all who live to see such times. But that is not for them to decide. All we have to decide is what to do with the time that is given us."  --  J.R.R. Tolkien: "The Lord Of The Rings: The Fellowship Of The Ring"
                  1. 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

                2. 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

                  --
                  "Love your nation - respect the others."
  2. 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