【原创】关于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开发已经有好几年了,见证了太多语言的崛起和陨落. 其实作为一个程序员最苦逼的事情莫过于每天要不停的追赶各大公司新出的框架和语 ...
随机推荐
- C#---爬虫抓取系列
以前就尝试过研究了一些爬虫程序,也找过一些爬虫抓取软件,效果不是很好. 今天正好一个培训的网友给了我一个视频,正好研究下,收获颇丰.感谢那位哥们~ 1.首先讨论一下抓取一个页面 这里我写了模仿写了一个 ...
- C# 3.0的新特性
自动属性. 之前定义属性的步骤: private filed + public property. 现在的形式:int id{get;set;}. 可以分别设置get/set的保护级别(protect ...
- JavaScript DOM编程艺术(第2版)学习笔记1(1~4章)
第一章 一些基本概念 HTML(超文本标记语言),构建网页的静态结构,由一系列的DOM组成: CSS(层叠样式表),给网页各部分结构添加样式: JavaScript,通过获取DOM给静态结构加上动作, ...
- Android使用Dribble Api
使用Dribble提供的Api获取上面的设计分享 使用了Material Design.SceneTransitionAnimation 使用了Volley Gson 1. 申请Dribble开发者应 ...
- Unity Android发布“Bundle Identifier has not been set up correctly”
原文:http://answers.unity3d.com/questions/162141/android-bundle-identifier-has-not-been-setup.html
- 路飞学城Python-Day29(第四模块-并发编程)
01-进程与程序的概念 并发:多进程和多线程 进程的概念:进程就是正在执行的过程,一个应用程序不是进程,只有应用程序启动以后才能说是进程,进程是一个抽象的概念,起源于操作系统 02-操作系统介绍 应用 ...
- 作用域与this
面向对象 一.单例模式 1.1 对象数据类型的作用: 把描述一个对象的属性和方法放在一个单独的空间,与其他的对象分割开,即时出现属性名相同的情况,也不会产生冲突 var name="xiao ...
- 变量命名规范及str类型
变量命名规范: 1.单词之间用_分开 add_num() 2.全局变量,大写 PI,NUMBER() 3.实例变量,以_开头 _example() 4.私有实例变量 __private() 5.普通函 ...
- C# 实现窗口程序winform像QQ一样靠近桌面边缘自动隐藏窗口
实现原理: 实现这个功能的原理步骤如下: 1.判断窗体程序是否靠近桌面边缘: 2.获取桌面屏幕大小与窗体程序大小: 3.把窗体程序显示在桌面以外隐藏起来,预留部分窗体方便用户拉出程序: 4.判断鼠标是 ...
- mysql存储小数
线下不知道什么版本的古董了,经本人亲测,varchar类型的数据,可以直接执行mysql的sum函数. ________________________________________________ ...