Postgres est la base de données
Puis-je utiliser une valeur NULL pour une clause IN? Exemple:
SELECT *
FROM tbl_name
WHERE id_field IN ('value1', 'value2', 'value3', NULL)
Je veux limiter à ces quatre valeurs.
J'ai essayé la déclaration ci-dessus et cela ne fonctionne pas, il s'exécute mais n'ajoute pas les enregistrements avec NULL id_fields.
J'ai également essayé d'ajouter une condition OR mais cela ne faisait que lancer la requête et la lancer sans fin visible.
SELECT *
FROM tbl_name
WHERE other_condition = bar
AND another_condition = foo
AND id_field IN ('value1', 'value2', 'value3')
OR id_field IS NULL
Aucune suggestion?
Une instruction
in
sera analysée de manière identique àfield=val1 or field=val2 or field=val3
. Mettre une valeur nulle à l'intérieur se résumera àfield=null
, ce qui ne fonctionnera pas.
( Commentaire par Marc B )
Je le ferais pour la clarté
SELECT *
FROM tbl_name
WHERE
(id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)
Votre requête échoue à cause de priorité de l'opérateur . AND
lie avant OR
!
Vous avez besoin d’une paire de parenthèses, ce qui n’est pas une question de "clarté", mais de pure nécessité logique.
SELECT *
FROM tbl_name
WHERE other_condition = bar
AND another_condition = foo
AND (id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)
Les parenthèses ajoutées empêchent la liaison AND
avant OR
. S'il n'y avait pas d'autres conditions WHERE
(pas AND
), vous ne seriez pas nécessaire parenthèses. La réponse acceptée est un peu trompeuse à cet égard.
SELECT *
FROM tbl_name
WHERE coalesce(id_field,'unik_null_value')
IN ('value1', 'value2', 'value3', 'unik_null_value')
Alors que vous éliminez le nul du chèque. Avec une valeur null dans id_field, la fonction coalesce renverrait «unik_null_value» à la place de null et, en ajoutant «unik_null_value» à la liste IN, la requête renverrait des publications où id_field est value1-3 ou null.
La question à laquelle Daniel a répondu est parfaitement correcte. Je voulais laisser une note concernant NULLS. Nous devons être prudents lors de l'utilisation de l'opérateur NOT IN lorsqu'une colonne contient des valeurs NULL. Vous n'obtiendrez aucune sortie si votre colonne contient des valeurs NULL et que vous utilisez l'opérateur NOT IN. Voici comment cela est expliqué ici http://www.oraclebin.com/2013/01/beware-of-nulls.html , un très bon article que je suis tombé sur et que j'ai pensé partager.
Remarque: Depuis que quelqu'un a prétendu que le lien externe est mort dans Sushant Butta answer, j'ai posté le contenu ici en tant que réponse séparée.
Méfiez-vous desNULLS.
Aujourd'hui, je suis tombé sur un comportement très étrange de requête en utilisant les opérateurs IN et NOT IN
. En fait, je voulais comparer deux tables et déterminer si une valeur de table b
existait dans table a
ou non et connaître son comportement si la colonne contenait des valeurs null
. Je viens donc de créer un environnement pour tester ce comportement.
Nous allons créer la table table_a
.
SQL> create table table_a ( a number);
Table created.
Nous allons créer la table table_b
.
SQL> create table table_b ( b number);
Table created.
Insérer des valeurs dans table_a
.
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.
Insérer des valeurs dans table_b
.
SQL> insert into table_b values(4);
1 row created.
SQL> insert into table_b values(3);
1 row created.
Nous allons maintenant exécuter une requête pour vérifier l'existence d'une valeur dans table_a
en vérifiant sa valeur à partir de table_b
à l'aide de l'opérateur IN
.
SQL> select * from table_a where a in (select * from table_b);
A
----------
3
Exécutez la requête ci-dessous pour vérifier la non-existence.
SQL> select * from table_a where a not in (select * from table_b);
A
----------
1
2
La sortie est venue comme prévu. Nous allons maintenant insérer une valeur null
dans la table table_b
et voir comment se comportent les deux requêtes ci-dessus.
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
La première requête s'est comportée comme prévu, mais que s'est-il passé avec la seconde requête? Pourquoi n'avons-nous pas eu de sortie, qu'est-ce qui aurait dû se passer? Y a-t-il une différence dans la requête? Non .
La modification est dans les données de la table table_b
. Nous avons introduit une valeur null
dans la table. Mais comment cela se fait-il? Divisons les deux requêtes en opérateurs "AND"
et "OR"
.
La première requête sera traitée en interne à peu près comme ceci. Donc, un null
ne créera pas de problème ici car mes deux premiers opérandes seront évalués à true
ou false
. Mais mon troisième opérande a = null
n'évaluera ni true
ni false
. Il sera évalué à null
uniquement.
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
La deuxième requête sera traitée comme ci-dessous. Puisque nous utilisons un opérateur "AND"
et que tout autre chose que true
dans aucun des opérandes ne me donnera aucune sortie.
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
Alors, comment traitons-nous cela? Nous choisirons toutes les valeurs not null
de la table table_b
en utilisant l'opérateur NOT IN
.
SQL> select * from table_a where a not in (select * from table_b where b is not null);
A
----------
1
2
Soyez donc toujours prudent avec les valeurs NULL
dans la colonne lorsque vous utilisez l'opérateur NOT IN
.
Attention à NULL !!
Je sais qu'il est tard pour répondre mais que cela pourrait être utile pour quelqu'un d'autre.
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)