想必大家都用过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. 使用Word 2013向cnblog发布博文

    Windows Live软件许久不更新,就想用手头的Word 2013作为cnblogs博客的撰写工具.在查看cnblogs关于Windows Live的配置说明时,发现下列有Word 2007的配置 ...

  2. JSON解析总结2

    使用json-lib-2.4-jdk15.jar JSON工具类: import java.util.List; import net.sf.json.JSONArray; import net.sf ...

  3. How to Use Rsync to Sync New or Changed/Modified Files in Linux

    As a system administrator or Linux power user, you may have probably come across or even on several ...

  4. PHP浮点数的精度

    在百度知道上看到这么一个问题 var_dump((0.3-0.2)==0.1); 结果是:false 后来查查手册,原来是浮点数的精度问题.那么0.3-0.2-0.1等于多少呢,结果:2.775557 ...

  5. 关于Windows® API Code Pack for Microsoft® .NET Framework

    相比之前的操作系统,Window 7(or Vista)提供了很多新特性,我们在应用实现中可以利用这些特性来提升用户体验. 这些特性主要包括以下几个方面: Shell Enhancements Dir ...

  6. tcp 和 udp 缓冲区的默认大小及设置【转】

    1. tcp 收发缓冲区默认值 [root@ www.linuxidc.com]# cat /proc/sys/net/ipv4/tcp_rmem   4096    87380   4161536 ...

  7. 一个简单的Spring测试的例子

    在做测试的时候我们用到Junit Case,当我们的项目中使用了Sring的时候,我们应该怎么使用spring容器去管理我的测试用例呢?现在我们用一个简单的例子来展示这个过程. 1 首先我们新建一个普 ...

  8. idea基本

    IntelliJ IDEA特色功能 IDEA所提倡的是智能编码,是减少程序员的工作,IDEA的特色功能有以下25点:智能的选取在很多时候我们要选取某个方法,或某个循环或想一步一步从一个变量到整个类慢慢 ...

  9. Codevs 1081 线段树练习2

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master   题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第 ...

  10. IPv6协议介绍

    IPv6是为了解决基于IPv4的TCP/IP协议簇遇到的问题而推出的下一代IP协议.由于IPv4中采用的编制方式使得可用的网络地址和主机地址的数目远低于理论数目,随着全球互联网的快速发展,现有的IPv ...