Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Problème avec valeur NOT IN ( valeur, null, valeur)


Sujet :

Langage SQL

  1. #1
    Membre éclairé
    Problème avec valeur NOT IN ( valeur, null, valeur)
    bonjour,

    Je cherche à selectionner les personnes qui n'ont pas fait le choix 44 parmis leurs 3 options facultatives (cat1 cat2 cat3). Les 3 champs sont des int, null possible.

    je fais une requête de ce style :

    select * from matable where 44 NOT IN (cat1,cat2,cat3).

    si j'ai (1,0,0) alors ça retourne bien la ligne donc NORMAL
    si j'ai (44,0,0) alors ça ne retourne pas la ligne donc NORMAL

    si j'ai (1,null,null), ça devrait me renvoyer la ligne puisque 44 n'est pas dans (1,null,null) or ce n'est pas le cas !

    En gros, dès que cat1 ou cat2 ou cat3 est null, ça ne me retourne pas a ligne, et je ne comprends pas pourquoi . est-ce que ça vient de mysql ?
    est-ce que comparer une valeur à null est impossible ?

    Ne me dites pas que je vais devoir encore coller des coalescence partout......

    Merci de vos conseils.

  2. #2
    Membre éclairé
    j'ai tenté une version avec des XOR

    select * from matable where (44<>cat1 XOR 44<>cat2 XOR 44<>cat3).

    mais ça me pose le même souci, quand cat1 ou cat2 ou cat3 contient null, alors c'est exclu malgré l'absence de 44 dans la liste des 3...bizarre.
    qu'est-ce que ce que je ne comprends pas....

  3. #3
    Membre éclairé
    bon, finalement avec des COALESCE ça fonctionne mais l'écriture ne me plait pas....

    select * from matable where 44 NOT IN (COALESCE(cat1,0),COALESCE(cat2,0),COALESCE(cat3,0))

    J'attends un avis avant de mettre RESOLU au forum.....

  4. #4
    Membre éclairé
    Bonjour,

    C'est le fameux cas du NOT IN avec des valeurs susceptibles d'être NULL. En fait NULL veut dire inconnu, donc 44 est peut-être l'une de ces valeurs inconnues, d'où le fait que la requête ne ramène rien, c'est logique.
    Tu n'as pas le choix en effet de tester si les valeurs sont null.

  5. #5
    Membre éclairé
    bonjour,

    je reviens avec une question.
    je suis sous mysql.

    je pense qu'il y a une subtilité.

    dans le cas de cette syntaxe ça marche :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    select * from matable where mon_champs NOT IN (cat1,cat2,cat3)


    et dans le cas de cette autre syntaxe (avec valeur) ça marche pas
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    select * from matable where 44 NOT IN (cat1,cat2,cat3)


    en gros, suivant qu'on mette un champ ou une valeur avant le NOT IN semble avoir une influence si on ne met pas les coael.

  6. #6
    Modérateur

    bonjour,


    êtes-vous certains de votre analyse ?

    normalement le comportement devrait être le même avec un littéral et avec une colonne...

    pouvez-vous détailler, avec éventuellement un jeu de test...

  7. #7
    Membre éclairé
    Citation Envoyé par aieeeuuuuu Voir le message
    bonjour,


    êtes-vous certains de votre analyse ?

    normalement le comportement devrait être le même avec un littéral et avec une colonne...

    pouvez-vous détailler, avec éventuellement un jeu de test...
    depuis la découverte de la nécessité de mettre le coal, je repasse sur de anciennes de requête afin de les corriger.
    et je me suis étonné de ne pas avoir reproduit le bug.

    D'ailleurs, est-ce un bug (de mysql dans mon cas) ou une particularité du langage sql ?
    je vais tenter de refaire plus de test simplifié pour comparer les cas.

    cas1 : 44 in (NULL , 44, NULL )
    avec
    cas 2 un_champ (NULL , 44,NULL )

    d'ailleurs, je me pose aussi la question de ce 3eme cas : NULL IN (NULL ,44, NULL ) ........

  8. #8
    Modérateur

    Il faut revenir aux bases de IN et NOT IN pour comprendre l'astuce avec les nulls.
    IN étant une factorisation de OR = , NOT IN étant une factorisation de AND <>.

    44 in (NULL , 44, NULL) se traduit par :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
        44 = null  -- faux (et toujours faux car null ne peut être ni égal ni différent à quoi que ce soit)
     or 44 = 44    -- vrai
     or 44 = null  -- faux

    Compte-tenu que ce sont des OR, l'expression globale est vraie.

    44 not in (NULL , 37, NULL) se traduit par :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
        44 <> null  -- faux (et toujours faux car null ne peut être ni égal ni différent à quoi que ce soit)
    and 44 <> 37    -- vrai
    and 44 <> null  -- faux

    Compte-tenu que ce sont des AND, l'expression globale est fausse.

###raw>template_hook.ano_emploi###