最近工作的时候遇到一个查询问题,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
–注:本人水平有限,如有问题或错误欢迎指正。–