SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差别:

IN:确定给定的值是否与子查询或列表中的值相匹配。
IN 关键字使您得以选择与列表中的任意一个值匹配的行。
当要获得居住在 California、Indiana 或 Maryland 州的所有作者的姓名和州的列表时,就需要下列查询:
SELECT ProductID, ProductName FROM Northwind.dbo.Products WHERE CategoryID = 1 OR CategoryID = 4 OR CategoryID = 5
然而,如果使用 IN,少键入一些字符也可以得到同样的结果:
SELECT ProductID, ProductName FROM Northwind.dbo.Products WHERE CategoryID IN (1, 4, 5)
IN 关键字之后的项目必须用逗号隔开,并且括在括号中。
下列查询在 titleauthor 表中查找在任一种书中得到的版税少于 50% 的所有作者的 au_id,然后从 authors 表中选择 au_id 与

titleauthor 查询结果匹配的所有作者的姓名:
SELECT au_lname, au_fname FROM authors WHERE au_id IN (SELECT au_id FROM titleauthor WHERE royaltyper < 50)
结果显示有一些作者属于少于 50% 的一类。

NOT IN:通过 NOT IN 关键字引入的子查询也返回一列零值或更多值。
以下查询查找没有出版过商业书籍的出版商的名称。
SELECT pub_name FROM publishers WHERE pub_id NOT IN (SELECT pub_id FROM titles WHERE type = 'business')

使用 EXISTS 和 NOT EXISTS 引入的子查询可用于两种集合原理的操作:交集与差集。两个集合的交集包含同时属于两个原集合的所有元素。

差集包含只属于两个集合中的第一个集合的元素。

EXISTS:指定一个子查询,检测行的存在。
本示例所示查询查找由位于以字母 B 开头的城市中的任一出版商出版的书名:
SELECT DISTINCT pub_name FROM publishers WHERE EXISTS (SELECT * FROM titles WHERE pub_id = publishers.pub_id AND type =

'business')
SELECT distinct pub_name FROM publishers WHERE pub_id IN (SELECT pub_id FROM titles WHERE type = 'business')
两者的区别:
EXISTS:后面可以是整句的查询语句如:SELECT * FROM titles
IN:后面只能是对单列:SELECT pub_id FROM titles

NOT EXISTS:
例如,要查找不出版商业书籍的出版商的名称:
SELECT pub_name FROM publishers WHERE NOT EXISTS (SELECT * FROM titles WHERE pub_id = publishers.pub_id AND type =

'business')
下面的查询查找已经不销售的书的名称:
SELECT title FROM titles WHERE NOT EXISTS (SELECT title_id FROM sales WHERE title_id = titles.title_id)

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/feixiang7443/archive/2010/04/21/5510012.aspx

 

 

另外,到底什么时候用IN  , 什么时候用  EXISTS?

 

1.exist,not exist一般都是与子查询一起使用. In可以与子查询一起使用,也可以直接in (a,b.....)
2.exist会针对子查询的表使用索引. not exist会对主子查询都会使用索引. in与子查询一起使用的时候,只能针对主查询使用索引. not in则不会使用任何索引. 注意,一直以来认为exists比in效率高的说法是不准确的。

in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
如果查询的两个表大小相当,那么用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要快。

3.exist与in都可以实现一个目的.二者都可以用来过滤数据.

示例:


select count(1) from t1;--160W
select count(1) from t2; --90W SELECT count(1)
FROM t1 a
WHERE EXISTS (SELECT accountid
FROM t2 b
WHERE a.keyid = b.keyid AND a.ideaid = b.ideaid);--主大子小,不适合使用exist,因为exist只会利用子表t2的复合索引keyid+ideaid,而子表内容要小与主表,主表由于无法使用索引,查询效率低下. select count(1) from t1 a where accountid in (SELECT accountid
FROM t2 b
WHERE a.keyid = b.keyid AND a.ideaid = b.ideaid);--主大子小,适合用in,因为in只会使用主表t1里面的复合主键keyid-ideaid,在主表大于子表的情况下,会很好的利用主表的索引. --后二条sql的执行结果都是一样的.说明exist与in在用法上可以达到一个目的,不同的地方是
--1.性能的考虑此时就按子表大主表小用exist,子表小主表大用in的原则就可以.
--2.写法的不同, exist的where条件是: "...... where exist (..... where a.id=b.id)"
--in的where条件是: " ...... where id in ( select id .... where a.id=b.id)"

4. exist的原理:

exists做为where 条件时,是先对where 前的主查询询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,如果为真则输出当前这一条主查询的结果,否则不输出

比如

如下:

表A

ID NAME

1 A1

2 A2

3 A3

表B

ID AID NAME

1 1   B1

2 2   B2

3 2   B3

表A和表B是一对多的关系 A.ID --> B.AID

SELECT ID , NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE A.ID = B.AID)

执行结果为

1 A1

2 A2

原因可以按照如下分析

SELECT ID , NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID = 1)

-->SELECT * FROM B WHERE B.AID = 1有值返回真所以有数据

SELECT ID , NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID = 2)

-->SELECT * FROM B WHERE B.AID = 2有值返回真所以有数据

SELECT ID , NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID = 3)

-->SELECT * FROM B WHERE B.AID = 3无值返回真所以没有数据

NOT EXISTS 就是反过来

SELECT ID , NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID = B.AID)

执行结果为

3 A3

5. in 与 =的区别

select name from student where name in ('zhang','wang','li','zhao');

select name from student where name='zhang' or name='li' or name='wang' or name='zhao'

的结果是相同的。

in的字段也可以与其它字段建复合索引.

比如

T1包含下面key, accountd,groupid.


SELECT   *
FROM T1 a
WHERE a.groupid = 2001
AND a.accountid = 1001
AND a.key IN ('abc', 'def', 'ala'); --上面的sql可以将accountid,key建成复合索引.

SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差别的更多相关文章

  1. 转【】浅谈sql中的in与not in,exists与not exists的区别_

    浅谈sql中的in与not in,exists与not exists的区别   1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表 ...

  2. 浅谈sql中的in与not in,exists与not exists的区别

    转 浅谈sql中的in与not in,exists与not exists的区别   12月12日北京OSC源创会 —— 开源技术的年终盛典 »   sql exists in 1.in和exists ...

  3. SQL 中详解round(),floor(),ceiling()函数的用法和区别?

    SQL 中详解round(),floor(),ceiling()函数的用法和区别? 原创 2013年06月09日 14:00:21   摘自:http://blog.csdn.net/yueliang ...

  4. (转)sql中 in 、not in 、exists、not exists 用法和差别

    exists (sql 返回结果集为真)  not exists (sql 不返回结果集为真)  如下:  表A  ID NAME  1    A1  2    A2  3  A3 表B  ID AI ...

  5. 浅谈sql中的in与not in,exists与not exists的区别以及性能分析

    1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的.如果查询的两个表 ...

  6. sql中 in 、not in 、exists、not exists 使用方法和区别

    % 的一类. NOT IN:通过 NOT IN keyword引入的子查询也返回一列零值或很多其它值. 以下查询查找没有出版过商业书籍的出版商的名称. SELECT pub_name FROM pub ...

  7. sql中的in与not in,exists与not exists的区别

    1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的.如果查询的两个表 ...

  8. sql中 in 、not in 、exists、not exists 用法和差别

    % 的一类. NOTIN:通过 NOTIN 关键字引入的子查询也返回一列零值或更多值. 以下查询查找没有出版过商业书籍的出版商的名称. SELECT pub_name FROM publishers ...

  9. sql中详解round(),floor(),ceiling()函数的用法和区别?

    round() 遵循四舍五入把原值转化为指定小数位数,如:round(1.45,0) = 1;round(1.55,0)=2floor()向下舍入为指定小数位数 如:floor(1.45,0)= 1; ...

  10. 关于sql中in 和 exists 的效率问题,in真的效率低吗

    原文: http://www.cnblogs.com/AdamLee/p/5054674.html 在网上看到很多关于sql中使用in效率低的问题,于是自己做了测试来验证是否是众人说的那样. 群众: ...

随机推荐

  1. Spring MVC的异步模式

    高性能的关键:Spring MVC的异步模式   我承认有些标题党了,不过话说这样其实也没错,关于“异步”处理的文章已经不少,代码例子也能找到很多,但我还是打算发表这篇我写了好长一段时间,却一直没发表 ...

  2. HDU 3277Marriage Match III(二分+并查集+拆点+网络流之最大流)

    题目地址:HDU 3277 这题跟这题的上一版建图方法差点儿相同,仅仅只是须要拆点.这个点拆的也非常巧妙,既限制了流量,还仅仅限制了一部分,曾经一直以为拆点会所有限制,原来也能够用来分开限制,学习了. ...

  3. Java引用类型具体解释

    JVM  的垃圾回收器对于不同类型的引用有不同的处理方式.java中对于一个对象来说,仅仅要有引用的存在,它就会一直存在于内存中.假设这种对象越来越多,超出了JVM中的内存总数,JVM就会抛出OutO ...

  4. 总结文件操作函数-文件夹(三)-C语言

    获取.改变当前文件夹: 原型为: #include <unistd.h>   //头文件 char *getcwd(char *buf, size_t size); //获取当前文件夹.相 ...

  5. jquery.ui.accordion的修改(支持展开多个)

    原文:jquery.ui.accordion的修改(支持展开多个) 背景:原jquery.ui.accordion插件,最多只能展开一个,不能展开多个,后来在网上找到了一个基于它的一个修改版(http ...

  6. Python什么是二次开发的意义?python在.net项目采用

    任何人都知道python在.net该项目是做什么的啊? 辅助用途,用作"二次开发"..net站点的话python主要是CGI才用.能够用python编写B/S程序. 解释一下二次开 ...

  7. 关于Platinum库的MediaRender具体C++代码实现探讨

    接上篇博文 NDK下 将Platinum SDK 编译成so库 (android - upnp) 讲述了如何利用该代码库编译给android程序调用的so库,其中也提到了,在使用sample-upnp ...

  8. SVN的switch命令

    语法就不说了,文档有的是,主要是两个常用的用法: . 切换资源库(svn sw --relocate) [plain] view plaincopy svn sw --relocate <fro ...

  9. centos安装Chromium

    1. Change root user Shell su - ## OR ## sudo -i 0 1 2 3 4   su - ## OR ## sudo -i   2a. Install NCSU ...

  10. xamarin跨平台iOS、Android 与Windows

    http://xamarin.csdn.net/ Xamarin是一个行动App开发平台,提供跨平台开发能力,开发人员透过Xamarin开发工具与程序语言,即可开发出iOS.Android 与Wind ...