【原创】关于not in的一些事情
早上到公司,收到一条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的使用场景和区别,见另一篇帖子:
【原创】关于not in的一些事情的更多相关文章
- LM-MLC 一种基于完型填空的多标签分类算法
LM-MLC 一种基于完型填空的多标签分类算法 1 前言 本文主要介绍本人在全球人工智能技术创新大赛[赛道一]设计的一种基于完型填空(模板)的多标签分类算法:LM-MLC,该算法拟合能力很强能感知标签 ...
- Django admin美化插件suit应用[原创]
前言 由于比较懒,自己弄了一个用户验证,没有自己写后台,用了django自带的user认证,并通过admin直接进行管理,但默认的admin并不漂亮,于是使用了这个django-suit插件,效果对比 ...
- 【原创】自己动手写工具----XSmartNote [Beta 3.0]
一.前面的话 在动笔之前,一直很纠结到底要不要继续完成这个工具,因为上次给它码代码还是一年多之前的事情,参考自己动手写工具----XSmartNote [Beta 2.0],这篇博文里,很多园友提出了 ...
- 【原创】自己动手写工具----签到器[Beta 2.0]
一.前面的话 上一篇中基本实现了简单的签到任务,但是不够灵活.在上一篇自己动手写工具----签到器的结尾中,我设想了几个新增功能来提高工具的灵活程度,下面把新增功能点列出来看看: (1)新增其他的进程 ...
- 【原创】轻量级移动设备即时通讯技术MobileIMSDK的常见问题解答
申明:MobileIMSDK 目前为个人原创开源工程且已发布,现整理了一些有关MobileIMSDK的常见的问题,希望对需要的人有用,谢谢.如需与作者交流,见文章底部个人签名处,互相学习. Mobil ...
- [原创]cocos2d-x研习录-第三阶 特性之物理引擎
游戏物理引擎是指在游戏中涉及物理现象的逻辑处理,它用于模拟现实世界的各种物理规律(如赛车碰撞.子弹飞行.物体掉落等),让玩家能够在游戏中有真实的体验. Cocos2D-x中支持Box2D和Chipmu ...
- 【原创】loadrunner12.53 录制脚本时 打不开网页或者打开网页慢?
问题描述: 之前刚装12.5版本时候,用 WebTours测试过,应用程序选择自己本地IE浏览器.exe程序,输入url地址就可以成功录制了 . 但是由于公司网络配置环境改变了(猜测),现 ...
- 玩转CSS3,嗨翻WEB前端,CSS3伪类元素详解/深入浅出[原创][5+3时代]
在我的上一篇博客中, 很多园友提出说对css3"画图"不是很理解, 在跟他们私聊了一段时间以后,加上自己在开始自学css3的时候的疑惑,我觉得大家之所以不是很理解主要是因为对伪元素 ...
- html5+css3实现跑动的爱心/动态水滴效果[原创][5+3时代]
大风起兮云飞扬,安得猛士兮走四方!html5+css3,不学不行. 做web开发已经有好几年了,见证了太多语言的崛起和陨落. 其实作为一个程序员最苦逼的事情莫过于每天要不停的追赶各大公司新出的框架和语 ...
随机推荐
- sql server 启用数据库的 Service Broker
使用SqlDependency时要开启Service Broker ,那么SqlDependency是什么 https://www.cnblogs.com/zhaoyihao/p/5663258.ht ...
- T7314 yyy的巧克力(钟)
题目描述 输入输出格式 输入格式: 如图 输出格式: 如图 输入输出样例 输入样例#1: 如图 输出样例#1: 如图 说明 如图 n*m-1 我们可以这样想,1*1的巧克力一定是由1*2的掰开的 #i ...
- UWP 读取XML文件
一.读取本地XML文件时要将xxx.xml文件的“生成操作”改为“嵌入的资源”会比较好,在手机上运行的话需要改为“内容” <?xml version="1.0" encodi ...
- css3背景渐变以及图片混合渲染模式(一)
一.CSS3 渐变(Gradients):CSS3 渐变(gradients)可以让你在两个或多个指定的颜色之间显示平稳的过渡. 以前,你必须使用图像来实现这些效果.但是,通过使用 CSS3 渐变(g ...
- luogu P3387 【模板】缩点_拓扑排序
还是很好些的. Code: #include <stack> #include <cstdio> #include <algorithm> #include < ...
- 浅谈自底向上的Shell脚本编程及效率优化
作者:沐星晨 出处:http://blog.csdn.net/sosodream/article/details/6276758 浅谈自底向上的Shell脚本编程及效率优化 小论文,大家多批评指导:) ...
- BZOJ 2150 部落战争 (二分图匹配)
题目大意:给你一个n*m的棋盘,有一些坏点不能走,你有很多军队,每支军队可以像象棋里的马一样移动,不过马是1*2移动的,而军队是r*c移动的,军队只能从上往下移动,如果一个点已经被一直军队经过,那么其 ...
- Windows 10快速在指定目录打开命令行
一.我们在想要到达的目录上按住shift键并点击鼠标右键.看到了吗,这时候在弹出菜单里多了一个选项,就是"在此处打开命令窗口",我们点开看一下. 二.不过有时候我们需要以管理员的权 ...
- [剑指offer] 7. 斐波那契数列 (递归 时间复杂度)
简介: 杨辉三角每条斜线上的数之和就构成斐波那契数列. 思路: 参考文章:https://mp.weixin.qq.com/s?src=11×tamp=1551321876& ...
- Git:与GitHub搭配及SSH登录
远程库(GitHub)上的地址 搭建本地库 准备一个文件 将地址用别名存在git上 推送到远程库 克隆 克隆的效果 1)完整的把远程库下载到本地 2)别名也完整保留 3)同时也初始化了本地库 邀请团队 ...