SQL 里的 EXISTS与in、not exists与not in
In和NotIn的使用注意事项和区别
In和NotIn的使⽤注意事项和区别总结:NULL值不能⽤⽤来+-*/, 不能⽤来<>, not in否则返回空或NULL即不可以 1. not in (select null),返回空2. not exists 如果条件中有null值,外层查询的null值会被返回。
3. in 和 exists 均会过滤掉条件中null值not In 相当于 <> all,如果 Not In 后⾯跟的是⼦查询的话,⼦查询中只要包含⼀个 null 的返回值,则会造成整个 Not in 字句返回空值,结果就是查询不会返回任何结果。
⽽ in 相当于 =any 的意思,可以有效处理⼦查询中返回空值的情况,返回正确的结果。
------------------------------------------------------------------------------------------------------not in ⽰例:--该例⼦想要返回没有下属的职员的姓名,如果⼦查询中有空值返回的话,则整个查询将没有结果返回SELECT st_nameFROM employees empWHERE emp.employee_id NOT IN (SELECT mgr.manager_id FROM employees mgr)说明:Null Values in a SubqueryThe SQL statement in the slide attempts to display all the employees who do not have anysubordinates. Logically, this SQL statement should have returned 12 rows. However, the SQLstatement does not return any rows. One of the values returned by the inner query is a null value and, therefore, the entire query returns no rowsThe reason is that all conditions that compare a null value result in a null. So whenever null valuesare likely to be part of the resultsset of a subquery, do not use the NOT INoperator. The NOT INoperator is equivalent to <> ALL.---------------------------------------------------------------------------------------------------------in 的⽰例:Notice that the null value as part of the results set of a subquery is not a problem if you use the INoperator. The IN operator is equivalent to =ANY. For example, to display the employees who have subordinates(下属), use the following SQL statement:SELECT st_nameFROM employees empWHERE emp.employee_id IN (SELECT mgr.manager_id FROM employees mgr);---------------------------------------------------------------------------------------------------------Alternatively, a WHERE clause can be included in the subquery to display all employees who do nothave any subordinates:--使⽤ Not In 的话,要注意除掉⼦查询中将要返回的空值SELECT last_nameFROM employeesWHERE employee_id NOT IN(SELECT manager_id FROM employees WHERE manager_id IS NOT NULL);。
sql中in和not not in的用法
sql中in和not not in的用法
在SQL中,IN 和NOT IN 是两个用于条件过滤的子句,它们允许我们在WHERE 子句中测试一个值是否存在于一个子查询或列表中。
1. IN的用法
IN 用于指定多个可能的值。
如果列中的值匹配列表中的任何一个值,条件就为真。
例如,如果我们想从一个名为students的表中选择名为John或Jane的学生,我们可以这样写:
sql
SELECT * FROM students WHERE name IN ('John', 'Jane');
2. NOT IN的用法
NOT IN 与IN 相反。
如果列中的值不匹配列表中的任何值,条件就为真。
例如,如果我们想从students表中选择除了John和Jane之外的所有学生,我们可以这样写:
sql
SELECT * FROM students WHERE name NOT IN ('John', 'Jane');
注意事项
使用IN和NOT IN时,列表中的值应该被正确地用括号括起来,并且每个值之间用逗号分隔。
当列表中的值很多时,使用IN或NOT IN可能会导致性能问题。
在这种情况下,考虑使用连接(JOIN)或其他优化策略。
当使用NOT IN时,如果子查询或列表返回NULL值,可能会导致意外的结果。
例如,如果有一个学生的名字是NULL,并且你执行上面的NOT IN查询,那么这个学生将不会被选中,即使你期望选择所有学生。
总之,IN和NOT IN是SQL中非常有用的条件过滤工具,但在使用时需要注意一些细节和潜在的性能问题。
sql 里exists 的用法
sql 里exists 的用法SQL言是当今世界最常用的数据库管理语言。
它的强大功能和便捷的使用方式为用户带来了无限的便利。
SQL言包含了大量的命令,这些命令被用来进行数据库查询和管理。
其中最重要的一个功能就是布尔函数,其中包括 EXISTS令。
EXISTS令用于检查一个表或子查询是否存在指定的数据。
如果该表或子查询存在指定的数据,该命令返回 true,如果不存在,则返回 false。
该命令可以有以下形式:【SELECT * FROM T WHERE EXISTS(S);】在上述形式中, T 为表,S 为子查询, EXISTS 为布尔函数,该函数的作用是检查T表中是否存在S子查询的结果。
如果存在这些结果,该函数返回 true,否则返回 false。
EXISTS际上是一个基于表的关系表达式,可以使用子查询来检查两个表之间的关系。
如果两个表之间存在指定的关系,该函数返回true,否则返回 false。
EXISTS数可以与其他查询条件一起使用。
例如,当你想要查询某一表中的数据时,你可以使用 EXISTS数来检查该表中是否包含某一特定字段的值。
你可以使用一些特定的条件来进行查询,例如:【SELECT * FROM T WHERE EXISTS (SELECT 1 FROM S WHERE =);】在上述查询中,T示要查询的表,S示子查询,Name 为查询字段。
该查询是检查T表中是否包含S表中某一名字,如果有,EXISTS数将返回 true。
此外,EXISTS数还可以与 NOT键字一起使用。
该关键字表示检索一个表中不存在指定值的记录。
例如:【SELECT * FROM T WHERE NOT EXISTS (SELECT 1 FROM S WHERE =);】在上述查询中, NOT Exists数会检索T表中不包含S表中任何一个名字的记录,如果不存在这样的记录,EXISTS数将返回 true。
EXISTS另一个重要用法是,可以使用 EXISTS数进行复杂的子查询。
SQL语句NOTIN优化之换用NOTEXISTS
SQL语句NOTIN优化之换⽤NOTEXISTSNOT IN查询⽰例(⽰例背景描述:根据条件查询Questions表得到的数据基本在PostedData表中不存在,为完全保证查询结果在PostedData表中不存在,使⽤NOT IN):SET STATISTICS PROFILE ON;SET STATISTICS IO ON;SET STATISTICS TIME ON;GO/*--你的SQL脚本开始*/SELECT A.IdFROM dbo.Questions A WITH ( NOLOCK )WHERE A.QuestionState ='正常'AND A.CheckTime >'2018-09-29 16:00:00'AND A.StateShowID NOT IN ( SELECT B.IntIdFROM dbo.PostedData BWHERE B.[Type]='question' );/*你的SQL脚本结束*/GOSET STATISTICS PROFILE OFF;SET STATISTICS IO OFF;SET STATISTICS TIME OFF;查询耗时如图:换⽤NOT EXISTS 查询⽰例:SET STATISTICS PROFILE ON;SET STATISTICS IO ON;SET STATISTICS TIME ON;GO/*--你的SQL脚本开始*/SELECT A.IdFROM dbo.Questions A WITH ( NOLOCK )WHERE A.QuestionState ='正常'AND A.CheckTime >'2018-09-29 16:00:00'AND NOT EXISTS ( SELECT B.IntIdFROM dbo.PostedData BWHERE B.[Type]='question'AND A.StateShowID = B.IntId );/*你的SQL脚本结束*/GOSET STATISTICS PROFILE OFF;SET STATISTICS IO OFF;SET STATISTICS TIME OFF;查询耗时如图:根据查询耗时明显可以看出,使⽤ NOT EXISTS ⽐NOT IN 的查询速度快很多。
SQL语句中exists和in的区别
SQL语句中exists和in的区别转⾃https:///liyasong/p/sql_in_exists.html 和 /lick4050312/article/details/4476333表展⽰ 查询中涉及到的两个表,⼀个user和⼀个order表,具体表的内容如下: user表: order表:in ⼀、确定给定的值是否与⼦查询或列表中的值相匹配。
in在查询的时候,⾸先查询⼦查询的表,然后将内表和外表做⼀个笛卡尔积,然后按照条件进⾏筛选。
所以相对内表⽐较⼩的时候,in的速度较快。
具体sql语句如下:1 SELECT2 *3 FROM4 `user`5 WHERE6 `user`.id IN (7 SELECT8 `order`.user_id9 FROM10 `order`11 ) 这条语句很简单,通过⼦查询查到的user_id 的数据,去匹配user表中的id然后得到结果。
该语句执⾏结果如下: 它的执⾏流程是什么样⼦的呢?让我们⼀起来看⼀下。
⾸先,在数据库内部,查询⼦查询,执⾏如下代码:SELECT`order`.user_idFROM`order` 执⾏完毕后,得到结果如下: 此时,将查询到的结果和原有的user表做⼀个笛卡尔积,结果如下: 此时,再根据我们的user.id IN er_id的条件,将结果进⾏筛选(既⽐较id列和user_id 列的值是否相等,将不相等的删除)。
最后,得到两条符合条件的数据。
⼆、select * from A where id in(select id from B)以上查询使⽤了in语句,in()只执⾏⼀次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加⼊结果集中,直到遍历完A表的所有记录. 它的查询过程类似于以下过程List resultSet=[]; Array A=(select * from A); Array B=(select id from B);for(int i=0;i<A.length;i++) { for(int j=0;j<B.length;j++) { if(A[i].id==B[j].id) { resultSet.add(A[i]); break; } } } return resultSet;可以看出,当B表数据较⼤时不适合使⽤in(),因为它会B表数据全部遍历⼀次. 如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差. 再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次,遍历次数⼤⼤减少,效率⼤⼤提升.结论:in()适合B表⽐A表数据⼩的情况exists ⼀、指定⼀个⼦查询,检测⾏的存在。
SQL中EXISTS的用法
SQL中EXISTS的⽤法⽐如在Northwind数据库中有⼀个查询为SELECT c.CustomerId,CompanyName FROM Customers cWHERE EXISTS(SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID)这⾥⾯的EXISTS是如何运作呢?⼦查询返回的是OrderId字段,可是外⾯的查询要找的是CustomerID和CompanyName字段,这两个字段肯定不在OrderID⾥⾯啊,这是如何匹配的呢?EXISTS⽤于检查⼦查询是否⾄少会返回⼀⾏数据,该⼦查询实际上并不返回任何数据,⽽是返回值True或FalseEXISTS 指定⼀个⼦查询,检测⾏的存在。
语法: 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 正好相反。
数据库EXISTS与NOTEXISTS
数据库EXISTS与NOTEXISTSEXISTS与NOT EXISTSEXISTS:表⽰存在xxx。
在查询的外层添加⼀个EXISTS,当内层查询有结果,则该EXISTS返回true,反之返回falseNOT EXISTS:表⽰不存在xxx。
在查询的外层添加⼀个NOT EXISTS,当内层查询有结果,则该NOT EXISTS返回false,反之返回true##表⽣成的过程 ``` SELECT Sname FROM Student WHERE NOT EXISTS(1) (SELECT * FROM Course WHERE NOT EXISTS(2) (SELECT * FROM SC WHERE Sno= Student.Sno AND Cno= o)); ``` ###学⽣表 ![](/blog/1017814/201704/1017814-20170422154233899-361931250.png) ###课程表 ![](/blog/1017814/201704/1017814-20170422154308962-74150998.png) ###学⽣选课表 ![](/blog/1017814/201704/1017814-20170422154327915-791639455.png)以上⾯的为例:⾸先改例⼦中有两个EXISTS,我们先从最⾥⾯的内容开始,当⼀个元组和课程表中的第⼀个元组在最⾥层循环中与SC.sno和o进⾏匹配的时候。
(情况1)若配上最内层的WHERE将该数据插⼊到临时表中,第⼀个NOT EXISTS(指内层的NOT EXISTS,代码中的(2))判断该临时表不为空则返回false。
(情况2)若没有匹配上最内层的WHERE返回false,则不将数据插⼊到临时的表中,第⼀个NOT EXISTS(是内层的NOT EXISTS,代码中的(2))判断结果表为空返回true####当Course循环结束之后 ####第⼆个NOT EXISTS(最外层的NOT EXISTS,代码上的(1))判断该内层返回集是否为空。
Oracle中in与exist,not in与not exist的性能问题
上星期五与haier讨论in跟exists的性能问题,正好想起原来公司的一个关于not in的规定,本想做个实验证明我的观点是正确的,但多次实验结果却给了我一个比较大的教训。
我又咨询了下oracle公司工作的朋友,确实是我持有的观点太保守了。
于是写个文章总结下,希望对大家有所启发。
后面可能有大篇是关于10053 trace的内容,只作实验证明,可直接忽略看最终的结论即可。
我们知道,in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
一直以来认为exists比in效率高的说法是不准确的。
如果查询的两个表大小相当,那么用in和exists是差别不大的。
但如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in,效率才是最高的。
假定表A(小表),表B(大表),cc列上都有索引:•select * from A where cc in(select ccfrom B); --效率低,用到了A表上cc列的索引•select * from A where exists(select cc from B where cc=A.cc); --效率高,用到了B 表上cc列的索引。
相反的:•select * from B where cc in (select cc from A); --效率高,用到了B表上cc列的索引•select * from B where exists(select ccfromA where cc=); --效率低,用到了A表上cc列的索引通过使用exists,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。
Oracle在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。
在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。
mysqlnotin、leftjoin、ISNULL、NOTEXISTS效率问题记录
mysqlnotin、leftjoin、ISNULL、NOTEXISTS效率问题记录语句⼀:select count(*) from A where A.a not in (select a from B)语句⼆:select count(*) from A left join B on A.a = B.a where B.a is null语句三:select count(*) from A where not exists (select a from B where A.a = B.a)知道以上三条语句的实际效果是相同的已经很久了,但是⼀直没有深究其间的效率对⽐。
⼀直感觉上语句⼆是最快的。
今天⼯作上因为要对⼀个数千万⾏数据的库进⾏数据清除,需要删掉两千多万⾏数据。
⼤量的⽤到了以上三条语句所要实现的功能。
本来⽤的是语句⼀,但是结果是执⾏速度1个⼩时32分,⽇志⽂件占⽤21GB。
时间上虽然可以接受,但是对硬盘空间的占⽤确是个问题。
因此将所有的语句⼀都换成语句⼆。
本以为会更快。
没想到执⾏40多分钟后,第⼀批50000⾏都没有删掉,反⽽让SQL SERVER崩溃掉了,结果令⼈诧异。
试了试单独执⾏这条语句,查询近⼀千万⾏的表,语句⼀⽤了4秒,语句⼆却⽤了18秒,差距很⼤。
语句三的效率与语句⼀接近。
第⼆种写法是⼤忌,应该尽量避免。
第⼀种和第三种写法本质上⼏乎⼀样。
假设buffer pool⾜够⼤,写法⼆相对于写法⼀来说存在以下⼏点不⾜:(1)left join本⾝更耗资源(需要更多资源来处理产⽣的中间结果集)(2)left join的中间结果集的规模不会⽐表A⼩(3)写法⼆还需要对left join产⽣的中间结果做is null的条件筛选,⽽写法⼀则在两个集合join的同时完成了筛选,这部分开销是额外的这三点综合起来,在处理海量数据时就会产⽣⽐较明显的区别(主要是内存和CPU上的开销)。
我怀疑楼主在测试时buffer pool可能已经处于饱和状态,这样的话,写法⼆的那些额外开销不得不借助磁盘上的虚拟内存,在SQL Server做换页时,由于涉及到较慢的I/O操作因此这种差距会更加明显。
in和not in的用法
in和not in的用法一、引言在数据库操作和编程中,`in` 和 `not in` 是常用的运算符,它们用于测试一个值是否存在于指定的集合中。
本文将详细介绍这两个运算符的用法,并通过示例来展示其应用。
二、`in` 的用法`in` 运算符用于测试一个值是否存在于指定的集合中。
如果值存在于集合中,则结果为真(即 `True`),否则为假(即 `False`)。
1. 数据库操作在数据库操作中,`in` 通常用于筛选符合特定条件的记录。
例如,在查询学生表中成绩在 A 到 C 之间的学生时,可以使用 `in` 运算符:```sqlSELECT * FROM students WHERE grade IN (A, B, C);```这将返回所有成绩在 A 到 C 之间的学生记录。
2. 编程语言在大多数编程语言中,`in` 运算符的使用方式类似。
以 Python 为例,假设我们有一个数字列表,并想检查一个数字是否在该列表中,可以使用 `in` 运算符:```pythonnumbers = [1, 2, 3, 4, 5]if 3 in numbers:print("数字 3 在列表中")else:print("数字 3 不在列表中")```这将输出 "数字 3 在列表中",因为 3 确实存在于列表中。
`not in` 运算符则用于测试一个值是否不存在于指定的集合中。
如果值不在集合中,则结果为真(即 `True`),否则为假(即 `False`)。
1. 数据库操作在数据库操作中,`not in` 常用于筛选不符合特定条件的记录。
例如,如果我们想查询所有成绩低于 A 的学生,可以使用 `not in`:```sqlSELECT * FROM students WHERE grade NOT IN (A, B, C);```这将返回所有成绩低于 A 的学生记录。
SQL优化的几种方法及总结
SQL优化的⼏种⽅法及总结优化⼤纲:通过explain 语句帮助选择更好的索引和写出更优化的查询语句。
SQL语句中的IN包含的值不应该过多。
当只需要⼀条数据的时候,使⽤limit 1。
如果限制条件中其他字段没有索引,尽量少⽤or。
尽量⽤union all代替union。
不使⽤ORDER BY RAND()。
区分in和exists、not in和not exists。
使⽤合理的分页⽅式以提⾼分页的效率。
查询的数据过⼤,可以考虑使⽤分段来进⾏查询。
避免在where⼦句中对字段进⾏null值判断。
避免在where⼦句中对字段进⾏表达式操作。
必要时可以使⽤force index来强制查询⾛某个索引。
注意查询范围,between、>、<等条件会造成后⾯的索引字段失效。
关于JOIN优化。
优化使⽤1、mysql explane ⽤法 explane显⽰了mysql如何使⽤索引来处理select语句以及连接表。
可以帮助更好的索引和写出更优化的查询语句。
EXPLAIN SELECT*FROM l_line WHERE `status` =1and create_at >'2019-04-11';explain字段列说明table:显⽰这⼀⾏的数据是关于哪张表的type:这是重要的列,显⽰连接使⽤了何种类型。
从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和allpossible_keys:显⽰可能应⽤在这张表中的索引。
如果为空,没有可能的索引。
可以为相关的域从where语句中选择⼀个合适的语句key:实际使⽤的索引。
如果为null,则没有使⽤索引。
很少的情况下,mysql会选择优化不⾜的索引。
这种情况下,可以在select语句中使⽤use index(indexname)来强制使⽤⼀个索引或者⽤ignore index(indexname)来强制mysql忽略索引key_len:使⽤的索引的长度。
sql中的exists
sql中的exists刚开始⼯作的开发,很容易过度的使⽤in、not in。
其实,在有些时候可以⽤exists、not exists来代替in和not in,实现查询性能的提升。
exists操作符时候会和in操作符产⽣混淆。
因为他们都是⽤于检查某个属性是否包含在某个集合中。
但是相同点也仅限于此。
exists的真正⽬的是检查⼦查询是否⾄少包含⼀条记录。
例如,下⾯的查询会返回⾏1和2:WITH numbers (nr) AS (SELECT 1 AS nr UNION ALLSELECT 2 AS nr UNION ALLSELECT 3 AS nr), letters (letter, nr) AS (SELECT 'A' AS letter, 1 AS nr UNION ALLSELECT 'B' AS letter, 2 AS nr)SELECT * FROM numbers n WHERE EXISTS (SELECT nr FROM letters WHERE nr= n.nr);当然,你也可以改写成in:WITH numbers (nr) AS (SELECT 1 AS nr UNION ALLSELECT 2 AS nr UNION ALLSELECT 3 AS nr), letters (letter, nr) AS (SELECT 'A' AS letter, 1 AS nr UNION ALLSELECT 'B' AS letter, 2 AS nr)SELECT * FROM numbers n WHERE n.nr IN (SELECT nr FROM letters);这两种写法,都可以返回相同的记录。
区别是exists会更快,因为在得到第⼀条满⾜条件的记录之后就会停⽌,⽽in会查询所有的记录(如果in返回很多⾏的话)。
SQL 语句优化原则
SQL 语句优化原则:1.IN 操作符用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。
但是用IN的SQL性能总是比较低的,从执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。
由此可见用IN的SQL至少多了一个转换的过程。
一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。
推荐方案:在业务密集的SQL当中尽量不采用IN操作符。
可以用exists代替。
SQL Server例子:Exists用法:select * from kj_dept where exists (select * from kj_dept_info where kj_dept.dept_id = dept_id and dept_id=XXX)in用法:select * from kj_dept where dept_id in (select dept_id from kj_dept_info where dept_id=XXX)2.NOT IN操作符此操作是强列推荐不使用的,因为它不能应用表的索引。
推荐方案:用NOT EXISTS 或(外连接+判断为空)方案代替。
3. <> 操作符(不等于)不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。
推荐方案:用其它相同功能的操作运算代替,如a<>0 改为a>0 or a<0a<>’’改为a>’’4.IS NULL 或IS NOT NULL操作(判断字段是否为空)判断字段是否为空一般是不会应用索引的,因为B树索引是不索引空值的。
推荐方案:用其它相同功能的操作运算代替,如a is not null 改为a>0 或a>’’等。
Oracle中in与exist,notin与notexist性能问题
上星期五与haier讨论in跟exists的性能问题,正好想起原来公司的一个关于not in的规定,本想做个实验证明我的观点是正确的,但多次实验结果却给了我一个比较大的教训。
我又咨询了下oracle公司工作的朋友,确实是我持有的观点太保守了。
于是写个文章总结下,希望对大家有所启发。
后面可能有大篇是关于10053 trace的内容,只作实验证明,可直接忽略看最终的结论即可。
我们知道,in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
一直以来认为exists比in效率高的说法是不准确的。
如果查询的两个表大小相当,那么用in和exists是差别不大的。
但如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in,效率才是最高的。
假定表A(小表),表B(大表),cc列上都有索引:•select * from A where cc in (select cc from B)。
--效率低,用到了A表上cc列的索引•select * from A where exists(select cc from B where cc=)。
--效率高,用到了B表上cc 列的索引。
相反的:•select * from B where cc in (select cc from A)。
--效率高,用到了B表上cc列的索引•select * from B where exists(select cc from A where cc=)。
--效率低,用到了A表上cc 列的索引通过使用exists,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。
Oracle在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。
在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。
sql中exists用法
sql中exists用法exists是SQL中的一种检查函数,用于判断一条SQL子句是否存在结果集,在SQL中exists的使用可以极大地提高查询效率。
exists函数相比"in"函数有很大的优势,即exists在找到结果情况下,会立刻返回True,而"in"函数会把所有结果查出来才进行判断。
如需要确定是否有顾客名叫“张三”的,一般会使用in函数:select * from customers where name in("张三");此SQL会把customers表中所有的name值为“张三”的记录拿出来,然后再处理,比较耗时的情况下,可以使用exists:select * from customers where exists(select 1 from customers where name = "张三");exists把结果集直接返回,无需在customers表上多余的查询,大大提高查询效率。
这也是当今大数据场景下exists函数受到青睐。
除了简单用法之外,exists函数还可以与其它结合起来使用,比如查找满足条件X和Y其中一个的记录:select * from customers where exists(select 1 from customers where name = "张三") or exists(select 1 from customers where name = ”Ping";由于存在exists函数,当今的查询任务变得超级快捷。
exists函数不仅用于极大地提升SQL查询效率,也可以启发我们在生活中不断改善效率,把更多时间留出来完成更有意义的事情。
SQLSERVER中关于exists和in的简单分析
SQLSERVER中关于exists和in的简单分析In与Exists这两个函数是差不多的,但由于优化⽅案不同,通常NOT Exists要⽐NOT IN要快,因为NOT EXISTS可以使⽤结合算法⼆NOT IN就不⾏了,⽽EXISTS则不如IN快,因为这时候IN可能更多的使⽤结合算法。
如图,现在有两个数据集,左边表⽰#tempTable1,右边表⽰#tempTable2。
现在有以下问题:1.求两个集的交集?2.求tempTable1中不属于集#tempTable2的集?先创建两张临时表:create table #tempTable1(argument1 nvarchar(50),argument2 varchar(20),argument3 datetime,argument4 int);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher001','130********',GETDATE()-1,1);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher002','23218757',GETDATE()-2,2);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher003','13018757',GETDATE()-3,3);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher004','13023257',GETDATE()-4,4);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher005','13023218',GETDATE()-5,5);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher006','13023218',GETDATE()-6,6);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher007','13023218',GETDATE()-7,7);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher008','13023218',GETDATE()-8,8);create table #tempTable2(argument1 nvarchar(50),argument2 varchar(20),argument3 datetime,argument4 int);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher001','130********',GETDATE()-1,1);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher0010','23218757',GETDATE()-10,10);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher003','13018757',GETDATE()-3,3);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher004','13023257',GETDATE()-4,4);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher009','13023218',GETDATE()-9,9);⽐如,我现在以#tempTable1和#tempTable2的argument1作为参照1.求两集的交集:1)in ⽅式select * from #tempTable2 where argument1 in(select argument1 from #tempTable1)2)exists ⽅式select * from #tempTable2 t2 where exists(select * from #tempTable1 t1 where t1.argument1=t2.argument1)2.求tempTable1中不属于集#tempTable2的集1)in ⽅式select * from #tempTable1 where argument1 not in(select argument1 from #tempTable2)2)exists ⽅式select * from #tempTable1 t1 where not exists(select * from #tempTable2 t2 where t1.argument1=t2.argument1)。
exist和notexist用法
exist和notexist⽤法--exists (sql 返回结果集,为真)--not exists (sql 不返回结果集,为真)--如下:--表AID NAME1 A12 A23 A3--表BID AID NAME11 B122 B232 B3--表A和表B是1对多的关系 A.ID => B.AIDSELECT ID,NAME FROM A WHERE EXIST (SELECT*FROM B WHERE A.ID=B.AID)--执⾏结果为1 A12 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=========================================================================== --EXISTS = IN,意思相同不过语法上有点点区别,好像使⽤IN效率要差点,应该是不会执⾏索引的原因SELECT ID,NAME FROM A WHERE ID IN (SELECT AID FROM B)--NOT EXISTS = NOT IN ,意思相同不过语法上有点点区别SELECT ID,NAME FROM A WHERE ID NOT IN (SELECT AID FROM B)。
sql语句中in与exist not in与not exist 的区别
sql语句中in与exist not in与not exist 的区别in和existsin 是把外表和内表作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=)效率高,用到了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=)效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。
所以无论那个表大,用not exists都比not in要快。
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'的结果是相同的。
sqlexists用法
sqlexists用法标题:深入理解与使用SQLExistsSQLExists是一个在SQL查询中非常重要的函数,主要用于检查是否存在满足特定条件的数据。
本文将详细解析SQLExists的用法,通过一步步的讲解和实例演示,帮助读者理解和掌握这个重要函数。
一、SQLExists的基本概念SQLExists是一个在许多关系型数据库系统中都存在的内置函数,如SQL Server、Oracle、MySQL等。
其基本语法为:EXISTS (subquery)其中,subquery是一个子查询,用于定义要检查的条件。
如果子查询返回任何行,那么EXISTS函数将返回TRUE;否则,它将返回FALSE。
二、SQLExists的使用场景SQLExists主要在以下几种场景中使用:1. 验证数据是否存在:在插入、更新或删除数据之前,可以使用SQLExists 检查数据库中是否已经存在相关数据,以避免重复或冲突。
2. 复杂查询中的过滤条件:在复杂的多表联查中,可以使用SQLExists 作为过滤条件,只返回那些在关联表中存在对应记录的行。
3. 实现特定的业务逻辑:在一些特定的业务场景中,如实现“如果存在则更新,不存在则插入”的操作,也可以利用SQLExists来实现。
三、SQLExists的使用步骤以下是一步一步使用SQLExists的示例:步骤一:定义子查询首先,我们需要定义一个子查询,该子查询将用于检查是否存在满足特定条件的数据。
例如,我们有一个名为"Employees"的表,我们想检查是否存在一个名叫"John Doe"的员工:sqlSELECT * FROM Employees WHERE EmployeeName = 'John Doe'步骤二:使用SQLExists然后,我们将上述子查询嵌入到SQLExists函数中:sqlEXISTS (SELECT * FROM Employees WHERE EmployeeName = 'John Doe')此语句将返回TRUE(如果存在名为"John Doe"的员工)或FALSE(如果不存在)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SQL 里的EXISTS与in、not exists与not in2011-01-07 10:01:25| 分类:sql | 标签:|字号大中小订阅系统要求进行SQL优化,对效率比较低的SQL进行优化,使其运行效率更高,其中要求对SQL中的部分in/not in修改为exists/not exists修改方法如下:in的SQL语句SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtimeFROM tab_oa_pub WHERE is_check=1 andcategory_id in (select id from tab_oa_pub_cate where no='1')order by begintime desc修改为exists的SQL语句SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtimeFROM tab_oa_pub WHERE is_check=1 andexists (select id from tab_oa_pub_cate where tab_oa_pub.category_id=convert(int,no) and no='1') order by begintime desc分析一下exists真的就比in的效率高吗?我们先讨论IN和EXISTS。
select * from t1 where x in ( select y from t2 )事实上可以理解为:select *from t1, ( select distinct y from t2 ) t2where t1.x = t2.y;——如果你有一定的SQL优化经验,从这句很自然的可以想到t2绝对不能是个大表,因为需要对t2进行全表的“唯一排序”,如果t2很大这个排序的性能是不可忍受的。
但是t1可以很大,为什么呢?最通俗的理解就是因为t1.x=t2.y可以走索引。
但这并不是一个很好的解释。
试想,如果t1.x和t2.y都有索引,我们知道索引是种有序的结构,因此t1和t2之间最佳的方案是走merge join。
另外,如果t2.y上有索引,对t2的排序性能也有很大提高。
select * from t1 where exists ( select null from t2 where y = x )可以理解为:for x in ( select * from t1 )loopif ( exists ( select null from t2 where y = x.x )thenOUTPUT THE RECORD!end ifend loop——这个更容易理解,t1永远是个表扫描!因此t1绝对不能是个大表,而t2可以很大,因为y=x.x可以走t2.y的索引。
综合以上对IN/EXISTS的讨论,我们可以得出一个基本通用的结论:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
我们要根据实际的情况做相应的优化,不能绝对的说谁的效率高谁的效率低,所有的事都是相对的//----------------------------------------------------------------------------------------------------------------------------------------------------------------学数据库的时候你们老师一定那选课那3个表做例子吧题目查询选修了全部课程的学生的姓名这是那三个表学生表:student sno,sname 0001,张三0002,李四0003,xxxx ... 课程表Course cno,cname 001,语文002,数学003,英语选课表sno,cno 0001,001 0001,002 0001,003 0002,001 0002,002 .... select Sname from student Where not exists (select * from Course where not exists (select * from sc where Sno=student.sno AND cno=o)) 咱们从最后一个select说起. select * from sc where Sno=student.sno AND cno=o 这个sql的意思就是遍历这三个表, 找到所有所有学生选修所有课程记的记录.. (select * from Course where not exists (select * from sc where Sno=student.sno AND cno=o)) 那么这条sql,依据上条sql的意思是,就是选中上条sql的相反的条件,就是加入某个学生没有选某个课程,就把这个记录查出来, 假如学生0003没有选课程003, 学生0004没有选001等等. 那么最后select Sname from student Where not exists (select * from Course where not exists (select * from sc where Sno=student.sno AND cno=o)) 这句就排除了所有没有选一门课的学生,只要某个学生没有选某们课,不管是哪一门,就在上面的sql过滤出来了,那么上句sql的相反的, 就是not exists (不符合上面sql结果的) 就是选全部课程的学生了我的表达意思不是很清楚,不知道能否看懂呢..... not exists的含义你可以google出来,上面几位也说的很清楚了这句三层嵌套语句就是这么个含义.... 当然,举一反三,你也可以写出, 被全部学生都选的课程,,,被全部学生都不选的课程,,,呵呵...//---------------------------------------------------------------------------------------------------sql exists和not exists用法MySql秘籍2007-12-29 16:49:44 阅读5921 评论0 字号:大中小订阅exists (sql 返回结果集,为真)not exists (sql 不返回结果集,为真)如下:表AID NAME1 A12 A23 A3表BID AID NAME1 1 B12 2 B23 2 B3表A和表B是1对多的关系 A.ID => B.AIDSELECT ID,NAME FROM A WHERE EXIST (SELECT * FROM B WHERE A.ID=B.AID)执行结果为1 A12 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====================================================================== =====EXISTS = IN,意思相同不过语法上有点点区别,好像使用IN效率要差点,应该是不会执行索引的原因SELECT ID,NAME FROM A WHERE ID IN (SELECT AID FROM B)NOT EXISTS = NOT IN ,意思相同不过语法上有点点区别SELECT ID,NAME FROM A WHERE ID NOT IN (SELECT AID FROM B)UNION与EXISTS简单用法关键词:UNION,EXISTSUNION:UNION 指令的目的是将两个SQL 语句的结果合并起来。
从这个角度来看,UNION 跟JOIN 有些许类似,因为这两个指令都可以由多个表格中撷取资料。
UNION 的一个限制是两个SQL 语句所产生的栏位需要是同样的资料种类。
另外,当我们用UNION这个指令时,我们只会看到不同的资料值(类似Select DISTINCT)。
union只是将两个结果联结起来一起显示,并不是联结两个表………… UNION 的语法如下:[SQL 语句1]UNION[SQL 语句2]UNION ALL 这个指令的目的也是要将两个SQL 语句的结果合并在一起。
UNION ALL 和UNION 不同之处在于UNION ALL 会将每一笔符合条件的资料都列出来,无论资料值有无重复。
UNION ALL 的语法如下:[SQL 语句1]UNION ALL[SQL 语句2]现在以实例来说明SQL Union的用法:(SQL Union All的用法是一样的。
只是SQL Union All 不会考虑记录是否有重复。
)比如:在一个会员表Users中有会员类型有两种,一种为VIP会员,另一种为普通会员,为VIP会员的在VIP字段中为yes,普通会员的在VIP字段为no。
要在前台显示10笔会员记录,其中五个最早注册的VIP会员和五个最早注册的普通会员,最早注册的VIP要排在最早注册的普通会员的前面。
SQL语句如下:select top 10 * from (select top 5 * from users where vip="yes"order by id desc union select top 10 * from users where vip="no"order by id desc) as usersEXISTS:系统要求进行SQL优化,对效率比较低的SQL进行优化,使其运行效率更高,其中要求对SQL中的部分in/not in修改为exists/not exists修改方法如下:in的SQL语句SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtimeFROM tab_oa_pub WHERE is_check=1 andcategory_id in (select id from tab_oa_pub_cate where no='1')order by begintime desc修改为exists的SQL语句SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtimeFROM tab_oa_pub WHERE is_check=1 andexists (select id from tab_oa_pub_cate where tab_oa_pub.category_id=convert(int,no) and no='1') order by begintime desc。