想必大家都用过sql中的in语句吧,我这里描述下我遇到的一种in语句问题,并总结一些给大家分享下,不对的地方还希望大虾指点下。

问题描述:IN子查询时,子查询中字段在表中不存在时语句却不报错

平常工作中我们会经常用到in或者not in语句来处理一些问题,比如通过in子查询语句检索符合或者不符合条件的集合结果、批量删除、修改一些符合条件或者不符合条件的集合。但大家是否注意到当子查询中字段名在表中不存在时语句不会报错(会返父查询中所有的结果),如果大家不注意这点,在使用in语句进行批量删除时就可能悲剧了。下面用实例来说明

 --一个简单的in查询语句
select * from tuser where userno in(select userno from filter_barcode)

上面这条语句子查询里,userno 并不存在filter_barcode表中,但是整个语句确能正常执行(执行子查询的话会报字段不存在的提示),而且返回的是tuser表中所有的结果集。如果大家不注意这种情况,一旦不是用来查询,是用来删除的,那整个表数据就被不知不觉给删除了。

但是当将子查询中userno字段改成一个即不再tuser也不再filter_barcode表中的字段,那语句就会报错

select * from tuser where userno in(select useno from filter_barcode)

Msg 207, Level 16, State 1, Line 1
列名 'useno' 无效。

原因:原来是在不使用表别名的前提下如果in子查询里字段在内表找不到就会去引用外表的。

现实情况下子查询引用外层查询的列是正常的,只不过一般不在in子查询中引用外层查询的列。
但是在exists,not exists子查询中用得比较多,

select a.* from tuser a where exists
(select top 1 * from filter_barcode b where a.userno=b.userno)
--执行上面这语句就会提示
Msg 207, Level 16, State 1, Line 1
列名 'userno' 无效。

以下四条是我从其他地方看到的,贴出来给大家参考

1.子表引用父表列,而自己没有,在子表有数据的情况下,返回所有非空键的父表记录,子表为空,则结果无
2.子表引用父表属性,只有最外层子查询才能引用
3.有前缀标识,按前缀,如果子表父表前缀一样,按4的规则
4.如果无前缀标识唯一性,子查询表也有此字段,那么以局部子查询为准
    如果前缀一样,子查询存在此字段,则以子查询表为准,否则以父表的为准

总结;为了避免这种问题有几个方法供大家参考

1、当需要用到in子查询时,先执行下in里面的子查询语句是否有误,如果误则进行相应修改

2、使用表前缀(别名)才是硬道理,例如

select * from tuser a where a.userno in(select b.userno from filter_barcode b)
Msg 207, Level 16, State 1, Line 1
列名 'userno' 无效。
--这样就会进行报错,而不会返回tuser所有的数据

3、使用exists语句来代替in语句

select a.* from tuser a where exists
(select top 1 * from filter_barcode b where a.userno=b.userno)
Msg 207, Level 16, State 1, Line 2
列名 'userno' 无效。

关于exists和in的区别用法这里就不在讲述,大家可以查询相关资料

对于in 和 exists的区别: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 ,另外IN是不对NULL进行处理。

关于sql语句in的使用注意规则的更多相关文章

  1. 关于sql语句in的使用注意规则( 转)

    select * from tuser where userno not in(select userno from filter_barcode) 上面这条语句子查询里,userno 并不存在fil ...

  2. [转帖]关于Java中SQL语句的拼接规则

    关于Java中SQL语句的拼接规则 自学demo 的时候遇到的问题 结果应该是 '"+e.getName()+"' 注意 一共有三组标点符号 (除去 方法函数后面的括号) 实现目标 ...

  3. SQL语句优化

    (1)      选择最有效率的表名顺序 ( 只在基于规则的优化器中有效 ) : ORACLE 的解析器按照从右到左的顺序处理 FROM 子句中的表名, FROM 子句中写在最后的表 ( 基础表dri ...

  4. 年终巨献 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  5. LINQ to SQL语句(17)之对象加载

    对象加载 延迟加载 在查询某对象时,实际上你只查询该对象.不会同时自动获取这个对象.这就是延迟加载. 例如,您可能需要查看客户数据和订单数据.你最初不一定需要检索与每个客户有关的所有订单数据.其优点是 ...

  6. SQL语句到底是怎么执行的

    写在前面的话:有时不理解SQL语句各个部分执行顺序,导致理解上出现偏差,或者是书写SQL语句时随心所欲,所以有必要了解一下sql语句的执行顺序.可以有时间自己写一个简单的数据库,理解会更加深入.下面就 ...

  7. SQL存储过程分页(通用的拼接SQL语句思路实现)

    多表通用的SQL存储过程分页 案例一: USE [Community] GO /****** Object: StoredProcedure [dbo].[Common_PageList] Scrip ...

  8. sql语句优化SQL Server

    MS   SQL   Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)          2.I/O吞吐量小,形成了 ...

  9. 改善SQL语句(转)

    二.改善SQL语句          很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解.比如:   select * from ta ...

随机推荐

  1. codeforces 676A A. Nicholas and Permutation(水题)

    题目链接: A. Nicholas and Permutation time limit per test 1 second memory limit per test 256 megabytes i ...

  2. hdu1331 按着题目的公式直接写

    #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #d ...

  3. GDB使用

    1.display val 设置显示格式 2.i b显示所有断点

  4. IntelliJ IDEA 中集成使用git(2015年06月10日)

    前提:需要有一个git账号,https://github.com/ 1.首先需要下载一个Github,https://windows.github.com 安装之后的界面是酱紫的,非常简洁美观 2.在 ...

  5. JavaScript之聊天室设计摸拟

    把聊天室的界面先做好,主代码(现在还只能单机模式・_・): window.onload = function(){ var arrIcon = ['http://tva1.sinaimg.cn/cro ...

  6. MVC 下 使用MvcPager分页控件

    先去下载 mvcpage http://mvcpager.codeplex.com/releases/view/64098只需要一个 MvcPager.dll文件即可 然后引用MvcPager.dll ...

  7. [转] 正则表达式 oracle

    地址:http://www.cnblogs.com/Azhu/archive/2012/04/03/2431127.html 从oracle database 10gsql 开发指南中copy的. 正 ...

  8. 【学习笔记】【C语言】二维数组

    1. 什么是二维数组 一个数组能表示一个班人的年龄,如果想表示很多班呢? 什么是二维数组?int ages[3][10]; 三个班,每个班10个人 相当于3行10列 相当于装着3个一维数组 二维数组是 ...

  9. Movie importing requires quicktime

    在Unity中使用MovieTexture播放视频会碰到movie importing requires quicktime的错误,解决方法如下: 1.关闭Unity安装QuickTime播放器,打开 ...

  10. 一个线程间的通讯小程序__(Java_Thread_Inout.Output)

    //多线程通讯 //多个线程处理同一资源,但是任务不同 //等待唤醒方法: //wait():将线程变成为冻结状态,线程会被存储在线程池中; //notify():唤醒线程中的一个线程(任意的) // ...