SQL NOT IN NULL 问题

最近工作的时候遇到一个查询问题,SQL如下:
select indicator.*FROM t_ind_indicator_info indicator WHERE indicator.STATUS = 1 AND indicator.FLAG = 1 AND indicator.MGRIND_TYPE = 1 AND indicator.id not in (select distinct t.indicator_id from t_ind_riskwarning_indicator t)

突然查询的时候为空了,然后查看数据库发现 indicator_id 有个为NULL 。

原来是在not in 的时候 NULL 会影响结果集为空的。

select from tableA where tableA.in not in (A,NULL) 相当于select from tableA where tableA.id <> A and tableA.id <> NULL 。 而在ANSI SQL中 <>null 返回的结果永远是0,即没有结果集,且不会提示语法错误。当一个有结果集的数据and一个无结果集的数据,最终结果为无结果集。

select from tableA where tableA.in in (A,NULL) 相当于select from tableA where tableA.id = A or tableA.id = NULL 。 而在ANSI SQL中 =null 返回的结果永远是0,即没有结果集,且不会提示语法错误。当一个有结果集的数据or一个无结果集的数据,最终结果为有结果集的数据。

因此not in 使用的时候一定要避免NULL的出现,最简单的可以使用

select * from A where A.id not in (select id from B where b.id IS NOT NULL)

not in 类似其它方法 join 和not exists。

not exists 方式

select indicator.*
   FROM t_ind_indicator_info indicator
WHERE indicator.STATUS = 1
   AND indicator.FLAG = 1
   AND indicator.MGRIND_TYPE = 1
   and   not exists
       (select 1 from t_ind_riskwarning_indicator t where t.indicator_id = indicator.id)

join 方式

 FROM t_ind_indicator_info indicator  left  join t_ind_achievement_indicator t on t.indicator_id = indicator.id
  where t.id is  null 
   and indicator.STATUS = 1
   AND indicator.FLAG = 1
   AND indicator.MGRIND_TYPE = 1  

–注:本人水平有限,如有问题或错误欢迎指正。–

点赞