Mysql
 sql >> Base de données >  >> RDS >> Mysql

Pourquoi le mot-clé MYSQL IN ne prend pas en compte les valeurs NULL

Ceci :

Error not in ('Timeout','Connection Error');

est sémantiquement équivalent à :

Error <> 'TimeOut' AND Error <> 'Connection Error'

Les règles sur la comparaison nulle s'appliquent également à IN. Donc, si la valeur de Error est NULL, la base de données ne peut pas rendre l'expression vraie.

Pour résoudre ce problème, vous pouvez procéder comme suit :

COALESCE(Error,'') not in ('Timeout','Connection Error');

Ou mieux encore :

Error IS NULL OR Error not in ('Timeout','Connection Error');

Ou mieux encore :

 CASE WHEN Error IS NULL THEN 1
 ELSE Error not in ('Timeout','Connection Error') THEN 1
 END = 1

OR ne court-circuite pas, CASE peut en quelque sorte court-circuiter votre requête

Peut-être qu'un exemple concret pourrait illustrer pourquoi NULL NOT IN expression ne renvoie rien :

Étant donné ces données :http://www.sqlfiddle.com/#!2/0d5da /11

create table tbl
(
  msg varchar(100) null,
  description varchar(100) not null
  );


insert into tbl values
('hi', 'greet'),
(null, 'nothing');

Et vous faites cette expression :

select 'hulk' as x, msg, description 
from tbl where msg not in ('bruce','banner');

Cela n'affichera que "salut".

Le NOT IN est traduit par :

select 'hulk' as x, msg, description 
from tbl where msg <> 'bruce' and msg <> 'banner';

NULL <> 'bruce' ne peut pas être déterminé, même pas vrai, même pas faux

NULL <> 'banner' ne peut pas être déterminé, même pas vrai pas même faux

Ainsi, l'expression de valeur nulle, résolue en fait :

can't be determined AND can't bedetermined

En fait, si votre SGBDR prend en charge le booléen sur SELECT (par exemple MySQL, Postgresql), vous pouvez comprendre pourquoi :http://www.sqlfiddle.com/#!2/d41d8/828

select null <> 'Bruce' 

Cela renvoie null.

Cela renvoie également null :

select null <> 'Bruce' and null <> 'Banner'

Étant donné que vous utilisez NOT IN , qui est essentiellement une expression ET.

NULL AND NULL

Résultats à NULL. C'est donc comme si vous faisiez un :http://www.sqlfiddle.com/# !2/0d5da/12

select * from tbl where null

Rien ne sera retourné