it-swarm.com.de

IN-Klausel mit NULL oder IS NULL

Postgres ist die Datenbank

Kann ich einen NULL-Wert für eine IN-Klausel verwenden? Beispiel:

SELECT *
FROM tbl_name
WHERE id_field IN ('value1', 'value2', 'value3', NULL)

Ich möchte mich auf diese vier Werte beschränken.

Ich habe die obige Anweisung ausprobiert und funktioniert nicht. Nun, sie führt die Datensätze mit NULL id_fields aus, fügt sie jedoch nicht hinzu.

Ich habe auch versucht, eine OR - Bedingung hinzuzufügen, aber dies führt dazu, dass die Abfrage ausgeführt wird und ohne Ende in Sicht ist.

SELECT *
FROM tbl_name
WHERE other_condition = bar
AND another_condition = foo
AND id_field IN ('value1', 'value2', 'value3')
OR id_field IS NULL

Irgendwelche Vorschläge? 

56
Phill Pafford

Eine in-Anweisung wird identisch mit field=val1 or field=val2 or field=val3 analysiert. Wenn Sie dort eine Null eingeben, wird auf field=null heruntergefahren.

( Kommentar von Marc B )

Ich würde dies aus Gründen der Klarheit tun

SELECT *
FROM tbl_name
WHERE 
(id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)
80
Daniel A. White

Ihre Abfrage schlägt fehl, weil Operator-Priorität ist. AND bindet vor OR!
Sie brauchen ein Paar Klammern, was keine "Klarheit" ist, sondern reines logische Notwendigkeit.

SELECT *
FROM   tbl_name
WHERE  other_condition = bar
AND    another_condition = foo
AND   (id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)

Die hinzugefügten Klammern verhindern, dass AND vor OR gebunden wird. Wenn es keine anderen WHERE-Bedingungen (keine AND) gäbe, würden Sie need _ Klammern nicht verwenden. Die akzeptierte Antwort ist in dieser Hinsicht etwas irreführend.

16
SELECT *
FROM tbl_name
WHERE coalesce(id_field,'unik_null_value') 
IN ('value1', 'value2', 'value3', 'unik_null_value')

Damit entfernen Sie die Null aus der Prüfung. Bei einem Nullwert in id_field würde die Coalesce-Funktion anstelle von null 'unik_null_value' zurückgeben. Durch Hinzufügen von 'unik_null_value zur IN-Liste würde die Abfrage Beiträge zurückgeben, bei denen id_field den Wert 1 bis 3 oder null hat.

7
Ove Halseth

Die von Daniel beantwortete Frage ist vollkommen in Ordnung. Ich wollte eine Notiz bezüglich NULLS hinterlassen. Wir sollten vorsichtig mit der Verwendung des NOT IN-Operators sein, wenn eine Spalte NULL-Werte enthält. Sie erhalten keine Ausgabe, wenn Ihre Spalte NULL-Werte enthält und Sie den Operator NOT IN verwenden. So wird es hier erklärt http://www.oraclebin.com/2013/01/beware-of-nulls.html , ein sehr guter Artikel, auf den ich gestoßen bin und gedacht habe, ihn zu teilen.

6
Sushant Butta

Hinweis: Da jemand behauptet hat, der externe Link sei in Sushant Buttas answer, habe ich den Inhalt hier als separate Antwort gepostet.

Hüten Sie sich vorNULLS.

Heute bin ich auf ein sehr merkwürdiges Abfrageverhalten gestoßen, als ich IN- und NOT IN-Operatoren verwendete. Eigentlich wollte ich zwei Tabellen vergleichen und herausfinden, ob ein Wert aus table b in table a vorhanden war oder nicht, und das Verhalten herausfinden, wenn die Spalte null-Werte enthält. Also habe ich gerade eine Umgebung erstellt, um dieses Verhalten zu testen.

Wir erstellen die Tabelle table_a.

SQL> create table table_a ( a number);
Table created.

Wir erstellen die Tabelle table_b.

SQL> create table table_b ( b number);
Table created.

Fügen Sie einige Werte in table_a ein.

SQL> insert into table_a values (1);
1 row created.

SQL> insert into table_a values (2);
1 row created.

SQL> insert into table_a values (3);
1 row created.

Fügen Sie einige Werte in table_b ein.

SQL> insert into table_b values(4);
1 row created.

SQL> insert into table_b values(3);
1 row created.

Jetzt führen wir eine Abfrage aus, um das Vorhandensein eines Werts in table_a zu überprüfen, indem der Wert von table_b mit dem Operator IN überprüft wird.

SQL> select * from table_a where a in (select * from table_b);
         A
----------
         3

Führen Sie die folgende Abfrage aus, um das Nichtvorhandensein zu prüfen.

SQL> select * from table_a where a not in (select * from table_b);
         A
----------
         1
         2

Die Ausgabe kam wie erwartet. Jetzt fügen wir einen null-Wert in die Tabelle table_b ein und sehen, wie sich die beiden obigen Abfragen verhalten.

SQL> insert into table_b values(null);
1 row created.

SQL> select * from table_a where a in (select * from table_b);
         A
----------
         3

SQL> select * from table_a where a not in (select * from table_b);

no rows selected

Die erste Abfrage verhielt sich wie erwartet, aber was ist mit der zweiten Abfrage passiert? Warum haben wir keine Ausgabe erhalten, was hätte passieren sollen? Gibt es einen Unterschied in der Abfrage? Nein .

Die Änderung betrifft die Daten der Tabelle table_b. Wir haben einen null-Wert in die Tabelle eingefügt. Aber wie kommt es, dass es sich so verhält? Lassen Sie uns die beiden Abfragen in den Operator "AND" und "OR" aufteilen.

Erste Abfrage:

Die erste Abfrage wird wie folgt intern behandelt. Eine null wird hier also kein Problem darstellen, da meine ersten beiden Operanden entweder true oder false auswerten. Mein dritter Operand a = null wird jedoch weder zu true noch zu false ausgewertet. Es wird nur zu null ausgewertet.

select * from table_a whara a = 3 or a = 4 or a = null;

a = 3  is either true or false
a = 4  is either true or false
a = null is null

Zweite Abfrage:

Die zweite Abfrage wird wie folgt behandelt. Da wir einen "AND"-Operator verwenden und nichts anderes als true in einem der Operanden eine Ausgabe liefert.

select * from table_a whara a <> 3 and a <> 4 and a <> null;

a <> 3 is either true or false
a <> 4 is either true or false
a <> null is null

Wie gehen wir damit um? Wir werden alle not null-Werte aus der Tabelle table_b auswählen, während Sie den NOT IN-Operator verwenden.

SQL> select * from table_a where a not in (select * from table_b where b is not null);

         A
----------
         1
         2

Seien Sie also stets vorsichtig mit NULL-Werten in der Spalte, während Sie den NOT IN-Operator verwenden.

Hüte dich vor NULL !!

2
1000111

Ich weiß, dass es zu spät ist, um zu antworten, könnte aber für andere nützlich sein

SELECT *
FROM (SELECT CASE WHEN id_field IS NULL 
                THEN 0 
                ELSE id_field 
            END AS id_field
      FROM tbl_name) AS tbl
WHERE tbl.id_field IN ('value1', 'value2', 'value3', 0)
0
ch2o