sql中exist()的用法
转自:https://www.cnblogs.com/netserver/archive/2008/12/25/1362615.html
比如在Northwind数据库中有一个查询为
SELECT c.CustomerId,CompanyName FROM Customers c
WHERE EXISTS(
SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID)
这里面的EXISTS是如何运作呢?子查询返回的是OrderId字段,可是外面的查询要找的是CustomerID和CompanyName字段,这两个字段肯定不在OrderID里面啊,这是如何匹配的呢?
EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
EXISTS 指定一个子查询,检测 行 的存在。
语法: EXISTS subquery
参数: subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。
结果类型: Boolean 如果子查询包含行,则返回 TRUE ,否则返回 FLASE 。
例表A:TableIn | 例表B:TableEx |
(一). 在子查询中使用 NULL 仍然返回结果集
select * from TableIn where exists(select null)
等同于: select * from TableIn
(二). 比较使用 EXISTS 和 IN 的查询。注意两个查询返回相同的结果。
select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
select * from TableIn where ANAME in(select BNAME from TableEx)
(三). 比较使用 EXISTS 和 = ANY 的查询。注意两个查询返回相同的结果。
select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
select * from TableIn where ANAME=ANY(select BNAME from TableEx)
NOT EXISTS 的作用与 EXISTS 正好相反。如果子查询没有返回行,则满足了 NOT EXISTS 中的 WHERE 子句。
结论:
EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS内部有一个子查询语句(SELECT ...
FROM...), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。
EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。
一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。
分析器会先看语句的第一个词,当它发现第一个词是SELECT关键字的时候,它会跳到FROM关键字,然后通过FROM关键字找到表名并把表装入内存。接着是找WHERE关键字,如果找不到则返回到SELECT找字段解析,如果找到WHERE,则分析其中的条件,完成后再回到SELECT分析字段。最后形成一张我们要的虚表。
WHERE关键字后面的是条件表达式。条件表达式计算完成后,会有一个返回值,即非0或0,非0即为真(true),0即为假(false)。同理WHERE后面的条件也有一个返回值,真或假,来确定接下来执不执行SELECT。
分析器先找到关键字SELECT,然后跳到FROM关键字将STUDENT表导入内存,并通过指针找到第一条记录,接着找到WHERE关键字计算它的条件表达式,如果为真那么把这条记录装到一个虚表当中,指针再指向下一条记录。如果为假那么指针直接指向下一条记录,而不进行其它操作。一直检索完整个表,并把检索出来的虚拟表返回给用户。EXISTS是条件表达式的一部分,它也有一个返回值(true或false)。
在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,可以通过使用 EXISTS 条件句防止插入重复记录。
INSERT INTO TableIn (ANAME,ASEX)
SELECT top 1 '张三', '男' FROM TableIn
WHERE not exists (select * from TableIn where TableIn.AID = 7)
EXISTS与IN的使用效率的问题,通常情况下采用exists要比in效率高,因为IN不走索引,但要看实际情况具体使用:
IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
------------------------------------------------------------------------
in 和exists
in是把外表和内表作hash 连接,而exists 是对外表作loop 循环,每次loop 循环再对内表进行查询。
一直以来认为exists 比in 效率高的说法是不准确的。如果查询的两个表大小相当,那么用in 和exists 差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:
表A(小表),表B(大表)1:
select * from A where cc in (select cc from B)
效率低,用到了A 表上cc 列的索引;
select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B 表上cc 列的索引。
相反的2:
select * from B where cc in (select cc from A)
效率高,用到了B 表上cc 列的索引;
select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A 表上cc 列的索引。
not in 和not exists
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists 都比not in 要快。
sql中exist()的用法的更多相关文章
- 十、SQL中EXISTS的用法 十三、sql server not exists
十.SQL中EXISTS的用法 EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False EXISTS 指定一个子查询,检测 行 的存在. 语法 ...
- SQL中distinct的用法
SQL中distinct的用法 1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...
- sql中binary_checksum(*)的用法
sql中binary_checksum(*)的用法(转) binary_checksum(*)可以用来检查修改过的行. 同一行在update后,该行的binary_checksum(*)就不同. 如 ...
- SQL中Merge的用法
SQL中Merge的用法 Merge的用法 Merge可以完成以下功能: 1. 两个表之间数据的更新 2. 进行进销存更新库存 3. 进行表之间数据的复制 语法说明: 1. 在语句结束后一定要 ...
- SQL中Truncate的用法(转)
转自:http://www.studyofnet.com/news/555.html 本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE TABLE用于删除表中的所 ...
- sql中 decode() 的用法
sql中 decode() 的用法 SELECT ID,DECODE(inParam,'Param','value1' ,'value2') name FROM yytj2018 如果 inParam ...
- SQL中Truncate的用法
SQL中Truncate的用法转自:http://www.studyofnet.com/news/555.html本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE ...
- SQL中CONVERT()函数用法详解
SQL中CONVERT函数格式: CONVERT(data_type,expression[,style]) 参数说明: expression 是任何有效的 Microsoft® SQL Server ...
- SQL中的declare用法
平时写SQL查询.存储过程都是凭着感觉来,没有探究过SQL的具体语法,一直都是按c#那一套往SQL上模仿,前几天项目中碰到一个问题引起了我对declare定义变量的作用域的兴趣. 大家都知道c#中的局 ...
随机推荐
- 接口测试之JMeter初探
1.JMeter安装配置 )登录 http://jmeter.apache.org/download_jmeter.cgi ,下载与自己的平台相对应文件: )安装JDK(.6以上),配置环境变量JAV ...
- 转载用sql语句计算出mysql数据库的qps,tps,iops性能指标
本帖最后由 LUK 于 2014-9-21 22:39 编辑 思路: 1 关注MYSQL三个方面的性能指标,分别为query数,transaction数,io请求数 2 在某个时间范围内(例如20秒) ...
- [转载]使用PHP模拟HTTP认证
[转载]使用PHP模拟HTTP认证 如果你希望在每个脚本的基础上实现口令保护功能,那么你可以通过结合header()函数和$PHP_AUTH_USER.$PHP_AUTH_PW全局变量的方法来创建一个 ...
- Javascript学习笔记--理解prototype
prototype和closure是js中两个不好搞懂的概念,幸好网上有很多相关的文章,在网上查了一遍以后,总是是觉得有点理解了.今天先说说prototype. 之前一直被ajax in action ...
- Android——使用 Intent传递类
定义要传递的类事,必须加上 public class Movie implements Serializable { } 传入类: public void onItemClick(AdapterVie ...
- 【Linux】使用 telnet 提示 Escape character is '^]'的意义
在linux/unix下使用telnet hostname port连接上主机后会提示Escape character is '^]' 这个提示的意思是按Ctrl + ] 会呼出telnet的命令行, ...
- 【2014年12月6日】HR交流会
今天的交流会感觉还是不错,体会到了一些东西,把它记下来. 想到什么写什么,可能没什么条理. 1.先选行业,再选职业,再选公司 根据自己的兴趣以及个人特长,能力等方面,需要定一个大概的方向,然后根据方向 ...
- could not bind to address 0.0.0.0:80 no listening sockets available, shutting down
在启动apache服务的时候(service httpd start 启动)出现这个问题. 出现这个问题,是因为APACHE的默认端口被占用的缘故.解决方法就是把这个端口占用的程序占用的端口去掉. 使 ...
- css笔记 - 张鑫旭css课程笔记之 absolute 篇
absolute地址 absolute绝对定位 绝对定位与浮动鲜为人知的兄弟关系 即是说,absolute后,元素和浮动元素的特性差不多,只不过absolute脱离文档流,元素飘在天上,float还在 ...
- 原生js--类的扩充和类型检测
扩充类的方法: 1.向原型对象上添加方法或属性.例如:Number.prototype.cl = function(){}; 但这种做法并不推荐,因为ES5之前,无法将这些新添加的方法或属性设置为不可 ...