oracle中的exists 和not exists 用法详解
- 格式:doc
- 大小:26.50 KB
- 文档页数:2
oracle中的exists和notexists⽤法测试⽤表A_⽤户表(test_table_A):测试⽤表B_存储物品表(test_table_B):1.exists操作select *from test_table_A Awhere exists(select 1from test_table_Bwhere owner = A.A_id);1执⾏结果:分步看其执⾏原理为:1> 从表A中第⼀条数据1001 tom开始,进⼊exsits函数,获取表B中第⼀条数据2001 1002 cup,判断(B.owner = A.A_id)是否为true,此处为false,因此获取表B中第⼆条数据2002 1001 car,判断(B.owner = A.id)是否为true,此处为true,则显⽰表A中第⼀条数据,不继续与表B中第三条数据做判断。
2> 从表A中第⼆条数据1002 jack开始,进⼊exsits函数,获取表B中第⼀条数据2001 1002 cup,判断(B.owner = A.A_id)是否为true,此处为ture,则显⽰A中第⼆条数据,不继续与表B中后续数据做判断。
3> 从表A中第三条数据1003 jenny开始,进⼊exsits函数,获取表B中第⼀条数据2001 1002 cup,判断(B.owner = A.A_id)为false,获取表中第⼆条数据2002 1001 car,判断(B.owner = A.id)为false,获取表B中第三条数据2003 1002 computer,判断(B.owner = A.id)为false,⾄此已与表B中所有数据判断完毕,均为false,因此最终结果不显⽰该语句。
2.not existsselect *from test_table_A Awhere not exists(select 1from test_table_Bwhere owner = A.A_id);执⾏结果:not exists操作即为反过来,当遇到true则不显⽰,全为false则显⽰。
EXISTS的使⽤详解1.exists的使⽤场合:exists⽤于只能⽤于⼦查询,可以替代in,若匹配到结果,则退出内部查询,并将条件标志为true,传回全部结果资料,in不管匹配到匹配不到都全部匹配完毕,使⽤exists 可以将⼦查询结果定为常量,不影响查询效果,⽽且效率⾼.2.in和exists对⽐:若⼦查询结果集⽐较⼩,优先使⽤in,若外层查询⽐⼦查询⼩,优先使⽤exists。
因为若⽤in,则oracle 会优先查询⼦查询,然后匹配外层查询,若使⽤exists,则oracle 会优先查询外层表,然后再与内层表匹配。
最优化匹配原则,拿最⼩记录匹配⼤记录.3.not exists的使⽤与exists 含义相反,也在⼦查询中使⽤,取出不满⾜条件的,与not in有⼀定的区别,注意有时候not exists不能完全替代not in.not exists和not in不同的情况:drop table test1;drop table test2;create table test1(a number,b number);create table test2(a number,b number);insert into test1 values(1,1);insert into test1 values(1,2);insert into test2 values(1,1);insert into test2 values(1,null);--使⽤not exists找出test1不在test2中的记录,都⽤b字段匹配--返回结果1,2select*from test1 t1where not exists(select1from test2 t2 where t1.b=t2.b);--使⽤not in,没有结果返回,因为test2中的b有nullselect*from test1 t1 where t1.b not in (select t2.b from test2 t2);--⽤相关⼦查询,结果同not existsselect*from test1 t1 where t1.b not in (select t2.b from test2 t2 where t1.b=t2.b);。
oracle中exist的用法在Oracle数据库中,EXISTS是一种用于检查子查询结果是否为空的关键字。
它可以用于WHERE子句或HAVING子句中,以便在查询中过滤掉不需要的数据。
在本文中,我们将深入探讨Oracle中EXISTS的用法,包括语法、示例和最佳实践。
语法EXISTS的语法如下:SELECT column1, column2, ...FROM table_nameWHERE EXISTS (SELECT column_name FROM table_name WHERE condition);其中,column1、column2等是要查询的列名,table_name是要查询的表名,condition是子查询中的条件。
如果子查询返回结果,则WHERE子句中的条件将被视为TRUE,否则将被视为FALSE。
示例让我们看一些使用EXISTS的示例。
1. 检查子查询结果是否为空假设我们有一个名为employees的表,其中包含员工的姓名和工资。
我们想要找到工资高于平均工资的员工。
我们可以使用以下查询:SELECT name, salaryFROM employees e1WHERE salary > (SELECT AVG(salary) FROM employees e2);但是,如果我们只想找到工资高于平均工资的员工中的前5个,我们可以使用EXISTS来实现:SELECT name, salaryFROM employees e1WHERE EXISTS (SELECT 1 FROM employees e2 WHERE e2.salary > (SELECT AVG(salary) FROM employees) AND e2.salary > e1.salary)AND ROWNUM <= 5;在这个查询中,我们使用了EXISTS来检查子查询的结果是否为空。
Oracle SQL NOT EXISTS用法(1)查询所有未选修“19980201”号课程的学生姓名和班号。
SELECT Sname,classno FROM Student WHERE NOT EXISTS(SELECT * FROM SC WHERE Sno=Student.SnoAND schoolno ='19980201')运行结果如图所示。
(2)查询选修了全部课程的学生姓名和班号。
分析:本例可转为查询没有一门课程不选的学生姓名和班号,代码如下:SELECT Sname,classno FROM Student WHERE NOT EXISTS(SELECT * FROM Sc WHERE NOT EXISTS(SELECT * FROM school WHERE NOT EXISTS(SELECT * FROM Course WHERE Cno=o AND school.Schoolno=sc.Schoolno AND sc.Sno=Student.Sno)));运行结果如图所示。
NOT EXISTS用法(1)NOT EXISTS用法(2)(3)查询至少选修了学生19980001选修的全部课程的学生编号和姓名。
分析:本题的查询要求可做如下解释,查询这样的学生,凡是19980001选修的课,他都选修了;换句话说,若有一个学号为x的学生,对所有课程y,只要学号为19980001的学生选修了课程y,则x也选修了y;那么就将他的学号选出来。
SELECT DISTINCT sno FROM SC SCX WHERE NOT EXISTS(SELECT * FROM SC SCY WHERE SCY .Sno='19980002' AND NOT EXISTS(SELECT * FROM SC SCZ WHERE SCZ .Sno= SCX .SnoAND SCZ.Schoolno=SCY.Schoolno));运行结果如图所示。
上星期五与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子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。
在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。
oracle中的exists和notexists⽤法详解from:/m136********/article/details/7007197exists表⽰()内⼦查询语句返回结果不为空说明where条件成⽴就会执⾏主sql语句,如果为空就表⽰where条件不成⽴,sql语句就不会执⾏。
not exists和exists相反,⼦查询语句结果为空,则表⽰where条件成⽴,执⾏sql语句。
负责不执⾏。
之前在学的时候,接触过exists,做过⼏个简单的例⼦,,如1.如果部门名称中含有字母A,则查询所有员⼯信息(使⽤exists)select * from emp where exists (select * from dept where dname like '%A%' and deptno = emp.deptno) temp and deptno=temp.deptno;结果为:EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- -------------- ---------- ---------- ----------7369 SMITH CLERK 7902 17-12⽉-80 800 207499 ALLEN SALESMAN 7698 20-2⽉ -81 1600 300 307521 WARD SALESMAN 7698 22-2⽉ -81 1250 500 307566 JONES MANAGER 7839 02-4⽉ -81 2975 207654 MARTIN SALESMAN 7698 28-9⽉ -81 1250 1400 307698 BLAKE MANAGER 7839 01-5⽉ -81 2850 307782 CLARK MANAGER 7839 09-6⽉ -81 2450 107788 SCOTT ANALYST 7566 19-4⽉ -87 3000 207839 KING PRESIDENT 17-11⽉-81 5000 107844 TURNER SALESMAN 7698 08-9⽉ -81 1500 0 307876 ADAMS CLERK 7788 23-5⽉ -87 1100 20EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- -------------- ---------- ---------- ----------7900 JAMES CLERK 7698 03-12⽉-81 950 307902 FORD ANALYST 7566 03-12⽉-81 3000 207934 MILLER CLERK 7782 23-1⽉ -82 1300 10已选择14⾏。
not exists 用法在SQL中,我们经常需要根据一些条件查询数据。
但是,有时候我们需要查询的数据是不存在于另一个表中的,这时候我们就需要用到 not exists 语句。
not exists 语句是一个布尔表达式,用于判断一个子查询是否为空。
如果子查询为空,则 not exists 语句返回 true,否则返回false。
not exists 语句常常用于查询某个表中不存在于另一个表中的数据。
not exists 语句的语法如下:```SELECT column1, column2, ...FROM table1WHERE NOT EXISTS (SELECT column1 FROM table2 WHERE condition);```其中,table1 是要查询的表,table2 是要比较的表,condition 是比较条件。
如果子查询返回的结果集为空,则 not exists 语句返回 true,否则返回 false。
下面是一个简单的例子,查询在 orders 表中不存在的客户信息: ```SELECT *FROM customersWHERE NOT EXISTS (SELECT * FROM orders WHERE customers.customer_id = orders.customer_id);```这个查询语句会返回在 customers 表中存在但在 orders 表中不存在的客户信息。
not exists 语句的使用可以帮助我们更加灵活地查询数据。
下面是一些常见的使用场景:1. 查询不存在于另一个表中的数据在实际应用中,我们经常需要查询某个表中不存在于另一个表中的数据。
比如,我们要查询没有下过订单的客户信息,可以使用如下语句:```SELECT *FROM customersWHERE NOT EXISTS (SELECT * FROM orders WHERE customers.customer_id = orders.customer_id);```2. 查询不存在于某个条件中的数据有时候,我们需要查询不存在于某个条件中的数据。
existsoracle的⽤法CREATE TABLE `A` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=29DEFAULT CHARSET=latin1CREATE TABLE `B` (`id` int(11) NOT NULL AUTO_INCREMENT,`AID` int(11) DEFAULT NULL,`name` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=29DEFAULT CHARSET=latin1SELECT ID,NAME FROM A WHERE EXISTS (SELECT1FROM B WHERE A.ID=B.AID) ;结果为:表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)===========================================================================EXISTS:系统要求进⾏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 descexists表⽰()内⼦查询语句返回结果不为空说明where条件成⽴就会执⾏主sql语句,如果为空就表⽰where条件不成⽴,sql语句就不会执⾏。
oracle的语句where 后面的exists的解释在Oracle数据库中,`WHERE`子句后面的`EXISTS`是一种条件表达式,用于检查子查询是否返回了任何行。
它的基本语法如下:```sqlSELECT column1, column2, ...FROM table_nameWHERE EXISTS (SELECT column_name FROM table_name WHERE condition);```这个语句的含义是,主查询中的条件成立的前提是子查询中存在至少一行数据。
如果子查询返回了任何行,那么`EXISTS`条件为真,主查询的结果将包含在`WHERE`子句中指定的列。
具体解释如下:1. 主查询(`SELECT column1, column2, ... FROM table_name`): 这是你希望从数据库中检索的数据的主要查询。
2. `WHERE EXISTS (`: 这是`EXISTS`条件的开始,表示接下来是一个子查询。
3. 子查询(`SELECT column_name FROM table_name WHERE condition`): 这是一个嵌套在主查询中的查询,用于检查某些条件是否在数据库中的特定表中满足。
4. `)`: 子查询的结束标记。
如果子查询返回了至少一行结果,主查询的条件就被认为是真,相应的数据将被检索。
否则,如果子查询没有返回任何行,主查询的条件被认为是假,相关的数据将不会被检索。
这种结构通常用于在一个表中检查另一个表是否存在符合某些条件的记录,从而进行有条件的查询或更新。
`EXISTS`常常与相关子查询一起使用,以便根据一个表中的值是否存在于另一个表中来进行条件过滤。
在数据库中,EXISTS 是一个用于查询的关键字,用于检查指定的条件是否存在。
它返回一个布尔值,如果满足条件的数据存在,则返回true,否则返回false。
EXISTS 通常与子查询一起使用,用于检查主查询中的条件是否存在于子查询的结果中。
如果子查询返回至少一行结果,则EXISTS 返回true,否则返回false。
以下是EXISTS 的用法示例:
1. 检查是否存在满足条件的数据:
```
SELECT column1, column2, ...
FROM table_name
WHERE EXISTS (SELECT column1 FROM table_name WHERE condition);
```
2. 使用EXISTS 来过滤查询结果:
```
SELECT column1, column2, ...
FROM table_name
WHERE EXISTS (SELECT column1 FROM table_name WHERE condition)
AND other_conditions;
```
3. 使用EXISTS 来判断是否存在相关记录:
```
SELECT column1, column2, ...
FROM table_name1
WHERE EXISTS (SELECT column1 FROM table_name2 WHERE condition);
```
在这些示例中,condition 是子查询的条件,可以根据实际需要进行调整。
有两个简单例子,以说明“exists”和“in”的效率问题
1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ;
T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高。
2) select * from T1 where T1.a in (select T2.a from T2) ;
T1数据量非常大而T2数据量小时,T1>>T2 时,2) 的查询效率高。
exists 用法:
请注意1)句中的有颜色字体的部分,理解其含义;
其中“select 1 from T2 where T1.a=T2.a”相当于一个关联表查询,相当于
“select 1 from T1,T2 where T1.a=T2.a”
但是,如果你当当执行1)句括号里的语句,是会报语法错误的,这也是使用exists需要注意的地方。
“exists(xxx)”就表示括号里的语句能不能查出记录,它要查的记录是否存在。
因此“select 1”这里的“1”其实是无关紧要的,换成“*”也没问题,它只在乎括号里的数据能不能查找出来,是否存在这样的记录,如果存在,这1)句的where 条件成立。
in 的用法:
继续引用上面的例子
“2) select * from T1 where T1.a in (select T2.a from T2) ”
这里的“in”后面括号里的语句搜索出来的字段的内容一定要相对应,一般来说,T1和T2这两个表的a字段表达的意义应该是一样的,否则这样查没什么意义。
打个比方:T1,T2表都有一个字段,表示工单号,但是T1表示工单号的字段名叫“ticketid”,T2则为“id”,但是其表达的意义是一样的,而且数据格式也是一样的。
这时,用2)的写法就可以这样:
“select * from T1 where T1.ticketid in (select T2.id from T2) ”
Select name from employee where name not in (select name from student);
Select name from employee where not exists (select name from student);
第一句SQL语句的执行效率不如第二句。
通过使用EXISTS,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。
Oracle在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。
在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。
这也就是使用EXISTS比使用IN通常查询速度快的原因。