首页 > 开发 > C > 正文

SQL NOT IN NULL 问题

2016-06-14 20:53:59  来源:慕课网
  最近工作的时候遇到一个查询问题,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 indicatorWHERE 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   --注:本人水平有限,如有问题或错误欢迎指正。--