早上到公司,收到一条cocall消息,是某哥们遇到的疑惑,可能很多新手并不知情:

请教个问题
我执行
1.   select * from t_htgl_htpswj t where t.c_wjmc = '山西'; 结果是 存在一条记录
2.   select * from t_htgl_fj t where t.c_wjmc = '山西';   结果是不存在记录
3. 为什么执行select  count(*) from t_htgl_htpswj htpswj where htpswj.c_wjmc not in (select fj.c_wjmc from t_htgl_fj fj  )
按照 1,2的执行结果,3的结果应该是至少是1才对呀,为什么实际执行结果是0呢。。。。   C_WJMC的类型都是VARCHAR(200)
很诡异的是 第三个查询,我如果用下面这个语句统计查询又是可以查询到结果的。。。。
select count(*) from t_htgl_htpswj htpswj where htpswj.c_wjmc not in (select fj.c_wjmc from t_htgl_fj fj where fj.n_xsxm_htps is not null)
我添加的这个子查询的条件好像和整体查询没有关系呀。。。

对于这个问题,需要了解以下两点内容:
1.null到底是个什么东西?
2.not in是如何执行的,什么原理?
下面看第一点:
1.null到底是个什么东西?我们知道在存储过程中:select a into b from t1 where c='';--如果返回的记录为零,那么会报错,此时实际上返回的就是一个null,一般在前面加一个count的判断再into。
null在oracle中代表什么都不是,空记录,这个地球人都知道,关键是在运算中,null和任何值的算术或者逻辑运算结果都是null,而且它和任何值都不相等,也非不相等,和自身也不相等,如:
select * from t1 where a=null;--查不到正确的记录
select * from t1 where null=null;--查不到记录。因此在判断空与非空时使用is null或者is not null来判断,以下是有个哥们让优化的sql:

..........
union all select C_BH,N_AJLB,C_AH,C_AJJC,C_AJMC,C_BH_SAR,D_BJRQ,C_BH_CBDW from t_ywgy_hztj_aj where n_ajlb = 202 and C_TBLX <> null union all select C_BH,N_AJLB,C_AH,C_AJJC,C_AJMC,C_BH_SAR,D_BJRQ,C_BH_CBDW from t_ywgy_hztj_aj where n_ajlb = 302 and C_TBLX <> null ...........

这样写是不对的,会获取不到正确的记录。应该这样写:
select * from t1 where a is null or b is not null;

插播一点,is null和is not null判断都是无法使用索引的,tom的书上有个很不错的提议,就是将null以一个值来代替,如果某列代码值为空,如不妨以-1来代表null,字符的话也可以以其他值(如‘null’)代替,这样在判断的时候可以使用索引。
2.not in 是如何执行的?
先看in是如何执行的:
如:

select * from t where a in(1,2,3);查询等价于:
select * from t where a=1 or a=2 or a=3;

如果条件有null呢?

select * from t where a in(1,2,3,null);等价于:
select * from t where a=1 or a=2 or a=3 or a=null;
--这是没有问题的,一般一样可以得到正确结果,因为a和null不相等,因此null值会被忽略

那么not in呢?

select * from t where a not in(1,2,3);--等价于
select * from t where a !=1 and a!=2 and a!=3;

如果这个条件中有null值呢?

select * from t where a not in(1,2,3,null);--等价于
select * from t where a !=1 and a!=2 and a!=3 and a!=null;

看a!=null,这个条件是不成立的,始终都是false,所以导致整个表达式为false,所以查不到任何记录。

回到开头的问题:

select  count(*) from t_htgl_htpswj htpswj where htpswj.c_wjmc not in (select fj.c_wjmc from t_htgl_fj fj  );

"select fj.c_wjmc from t_htgl_fj fj",这个sql中c_wjmc返回的结果是否包含null值呢?
我们执行以下sql:
select count(*) from t_htgl_fj fj where fj.c_wjmc is null;
----------
COUNT(*)
30
----------
所以,子查询中的c_wjmc存在null值,导致整个where的逻辑运算结果为false,因此没有返回任何结果。
那么为什么

“select count(*) from t_htgl_htpswj htpswj where htpswj.c_wjmc not in (select fj.c_wjmc from t_htgl_fj fj where fj.n_xsxm_htps is not null)”查询就能返回结果呢?

select fj.c_wjmc from t_htgl_fj fj where fj.n_xsxm_htps is not null;--这个查询中c_wjmc有没有空值呢?
执行以下查询:

select count(*) from thims.t_htgl_fj fj where fj.n_xsxm_htps is not null and c_wjmc is null;--n_xsxm_htps为空且c_wjmc也为空的记录:
----------
COUNT(*)
0
----------

这个查询中恰巧n_xsxm_htps is not null将所有的c_wjmc为null的记录过滤掉了,所以子查询中没有null值,所以能查到正确的结果。

结论:在not in的查询中,如果子查询结果中包含null值,将查不到记录,not in无法处理null值。因此可以使用exists,如果非要使用not in,也要保证在子查询中将null值过滤掉。
通常情况下,exists效率要高于in,而且exists可以准确的处理null值(其实是事先过滤掉罢了,不再赘述),关于exists和in的使用场景和区别,见另一篇帖子:

转载于:https://www.cnblogs.com/zhangxsh/p/3494414.html

【原创】关于not in的一些事情相关推荐

  1. 自媒体运营要知道的哪些知识

    1,微信公众平台 微信公众号,大家都知道.载体是微信手机客户端,海量用户,营销效果超好,它的公众平台是目前最热的.不过阅读率比较低,占20%左右. 操作比较简单,现在有很多的微信编辑器,更快的做好文章 ...

  2. 门户网站新闻资讯整站打包带全自动采集

    介绍: 下午发了模板,那个模板价值499.但是有了模板没有全自动采集相信大多数人都搞不懂,目录那么多,全靠原创几乎是不可能的事情,除非你是大公司,每人控制一个板块, 这套源码里面最有价值的应该是这个采 ...

  3. 100条超实用微信营销技巧:公众号、朋友圈和微信营销

    现在很多人都在说微营销,但大部分企业和个人都不知道怎么玩.用长篇大论的文章,写起来太累,看起来也很累,干脆整理成小技巧,这里的技巧包括了公众号和个人号的小技巧,都比较实用.下面一一分享给大家. 1. ...

  4. 微信价值观---张小龙首次公开演讲

    在广州举行的微信公开课PRO版活动上,腾讯公司高级执行副总裁.微信事业群总裁张小龙于上午意外现身. 在微信公开课PRO版正式开幕的前夜,一则有关微信公开课策划的谣言在朋友圈意外传播开来,给微信团队带来 ...

  5. “微信之父”张小龙首次演讲实录:详解微信平台四大价值观

    "微信之父"张小龙首次演讲实录:详解微信平台四大价值观(转) 1月11日上午,正在广州举行的"2016 微信公开课PRO版"上,被称为"微信之父&qu ...

  6. 平均每天有1.6个直男在虎扑发问:“我被绿了,该怎么办?”

    被领导刁难即将失业.被家人嫌弃.被查出癌症末期--最近热播的电视剧<我是余欢水>,刻画了一位近年最惨的男主角. 而对于虎扑直男们来说,最能get到的惨点是主角被绿了. 这部剧开播不久,虎扑 ...

  7. 听洞口一中校友张小龙(微信之父)的演讲有感

    洞口一中校友(学长)张小龙首次公开演讲 我不要感到意外了,听说张小龙是洞口的我也惊讶,然后我们在同一所高中上过学,我为我的母校出现这样的人而骄傲. 以用户的价值为依归.好的产品确实需要这样,这个毋庸置 ...

  8. 照片加水印怎么弄?方法步骤介绍

    照片加水印怎么弄?一些喜欢玩摄影的小伙伴在拍摄到一张完美的作品后,喜欢将照片分享到网上给大家欣赏,不过也时常会带来一些不愉快的事情发生,自己的分享出去的照片被别人恶意下载盗用,甚至冒充为自己的原创作品 ...

  9. JAVA有没有moba游戏_网易这款原创MOBA游戏,做了《王者荣耀》没有做的事情!

    大渣好,我叫呆毛哥,是爱搞事情的小爆哥的家庭老湿,不!是家庭老师. 提到MOBA手游,相信大家第一反应就是<王者荣耀>,甚至有一些人会把两者做等号,由此可见<王者荣耀>的统治地 ...

  10. mysql sql wait 写法_有关SQL语句写法注意的那些事情(原创整理)

    前段时候针对开发做的SQL语句写法方面注意点的培训, 特意总结了一下,也共享一下. 书写SQL需要注意的若干问题(MySQL版) 一.基本问题 1,在系统中运行的SQL查询,先考虑一下能不能在Slav ...

最新文章

  1. Selenium 1.0的历史及工作原理
  2. 荣耀有可能搭载鸿蒙系统吗,如果荣耀Magic3搭载了屏下镜头和鸿蒙系统,你会做第一批吗?...
  3. 灰度图像--图像增强 锐化基础
  4. 网页MSN,QQ,Skype,贸易通,雅虎通在线客服代码合集
  5. 滴滴开源的分布式id生成系统
  6. 让select查询结果随机排序
  7. 计算机中那些事儿(七):近期拆计算机小感
  8. Python3异常-AttributeError: module 'sys' has no attribute 'setdefaultencoding'
  9. Eclipse中如何安装Spring Tool Suite(STS)
  10. excel mysql乱码_excel打开是乱码的解法方法
  11. N-gram详解分析
  12. Python学习日记04
  13. FT60F011A包含1Krom+EEPROM+Flash方案
  14. win7语音识别--转
  15. Kotin 的代理和委托
  16. urovo手持终重启_手持终端设备常见问题及维修方法
  17. 福建农商银行计算机类笔试题目,2014年福建农商银行考试计算机模拟题
  18. dcu故障是哪_【车匠在线-故障案例】潍柴自主DCU通讯故障
  19. 微信小程序如何获取数组下标
  20. swift单元测试(三)XCTest之UI测试UITest

热门文章

  1. Unity3d实现加载PPT文件并展示
  2. 微信知乎B站赚钱套路揭秘… 如何把高考猛人忽悠瘸?(附人类简史电子书)
  3. AxMath安装教程
  4. Andrew Ng宣布离职百度:将开启在人工智能领域的新篇章
  5. SQLDMO类在C#中的应用
  6. 海明码(汉明码,汉明距离)
  7. 解决问题:远程电脑时出现发生身份验证错误,要求的函数不支持。
  8. TQ2440之移植linux 内核
  9. 基于物联网地铁自动售票检票智能系统
  10. 昆仑通态与欧姆龙温控器 台达变频器 联合通讯