SQL Server : Traitement des NULL dans des égalités ou de l’intérêt du IS NULL
Petit suite à une question en interne. Pourquoi se fait il qu'il ne soit pas possible de faire une égalité avec un NULL, tel que :
SELECT *
FROM MaTable
WHERE MonChamp = NULL
Requête qui ne reverra aucun résultat, ou même chose dans le cas suivant avec NOT IN.
SELECT *
FROM MaTable
WHERE MonChamp NOT IN(1, 2, NULL)
Pour le comprendre il faut revenir à la définition du NULL. Le problème du NULL ce sont ses définitions multiples, ce n'est pas une valeur. On l'utilise quand on ne connait pas la valeur ou que ne sait pas la déterminer. De ce fait la norme SQL a déterminé que l'égalité avec un NULL n'est pas quelque chose que l'on sait définir car le NULL correspond à n'importe quelle valeur possible pour le champ. D'un côté j'ai une valeur de l'autre NULL, le résultat ne peut donc être connu.
Le résultat est que pour la norme SQL, une égalité avec NULL renvoie toujours UNKNOWN. C'est aussi le cas pour SQL Server cependant on ne peut pas tester ni afficher cette valeur, il renverra pour sa part FAUX !
Mon premier exemple se comprend alors, et c'est pour cette raison que le « IS NULL » existe pour tester un champ dont la valeur serait inconnue :
SELECT *
FROM MaTable
WHERE MonChamp IS NULL
Pour le deuxième c'est un peut plus complexe. Il faut savoir que le IN en réalité n'est autre que le synonyme de = ANY. De ce fait ma seconde requête s'écrit aussi (invalide sur SQL Server, mais dans l'idée)
SELECT *
FROM MaTable
WHERE NOT MonChamp = ANY(1, 2, NULL)
Ce qui se simplifie encore en :
WHERE NOT(MonChamp = 1 OR MonChamp = 2 OR MonChamp = NULL)
-- ou --
WHERE MonChamp != 1 AND MonChamp != 2 AND MonChamp != NULL
Explication…
MonChamp = NULL donne à UNKNOWN
MonChamp != NULL donne à UNKNOWN
Prenons la seconde ligne, en la simplifiant successivement :
WHERE TRUE AND TRUE AND UNKNOWN
WHERE TRUE AND TRUE AND FALSE
WHERE FALSE
Ceci est due que le AND ne renverra VRAI que si toutes les conditions sont VRAI. Et comme la valeur UNKNOWN de fin condition de condition force le FAUX…
Voilà pourquoi le NOT IN avec une valeur NULL renverra toujours une condition fausse. C'est l'une des raisons pour lesquels il faut faire attention au NOT IN.
Bon nulls…
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :