专题:SQL之EXISTS
exists是用来判断是否存在的,当exists(查 是用来判断是否存在的, 是用来判断是否存在的 查 中的查询存在结果时则返回真, 询)中的查询存在结果时则返回真,否则返 中的查询存在结果时则返回真 回假。 回假。not exists则相反 则相反 它所在的查询属于相关子查询, 它所在的查询属于相关子查询,即子查询的 查询条件依赖于外层父查询的某个属性值, 查询条件依赖于外层父查询的某个属性值, 处理过程一般为: 处理过程一般为:
8
思路一( ) 思路一(in)
select Sname from student where Sno IN (select Sno from SC group by Sno //根据 根据Sno分组,统计每个 分组, 根据 分组 //学生选修了几门课程。如果等于 学生选修了几门课程。 学生选修了几门课程 如果等于course的 的 //总数,就是我们要找的 总数, 总数 就是我们要找的Sno having count(*) = (select count(*) from course ) ) //统计 统计course中共有几门课程 统计 中共有几门课程
6
1、查询选修了全部课程的学生姓名 、
7
思路一( ) 思路一(in)
首先学生的选课信息存在于SC表中, 首先学生的选课信息存在于 表中, 要想 表中 知道某个学生是否选修了全部课程, 知道某个学生是否选修了全部课程,至少我 们需要知道一共有几门课程。 们需要知道一共有几门课程。 其次,学生选修了与否,我们又要扫描SC 其次,学生选修了与否,我们又要扫描 全表, 全表,统计出选修了所有课程的学生号 最后在STUDENT表中根据学生号打出姓名 最后在 表中根据学路二(EXISTS) )
select Sname from student where NOT exists // (select * from course where NOT exists //不存在的提 不存在的提 //交给 交给course 交给 (select * from SC where Sno = student.sno and cno = o) // 代//入 入 两个未知变量 )
16
取外层查询的第一个元组, 取外层查询的第一个元组,根据它与内层查询 相关的属性值处理内层查询, 相关的属性值处理内层查询,若where子句返回 子句返回 true,则将此元组放入结果表,然后取下一个元 ,则将此元组放入结果表, 组,重复这个过程直到全部检查完为止
2
做为where 条件时,是先对 条件时, 即:exists做为 做为 where 前的主查询进行查询,然后用主查询 前的主查询进行查询, 的结果一个一个的代入exists的子查询进行 的结果一个一个的代入 的子查询进行 判断, 判断,如果为真则输出当前这一条主查询的 结果, 结果,否则不输出
10
select Cname from course where not exists//找不到的组合,提交 找不到的组合, 找不到的组合 提交course (select * from SC where o = cno and sno = ''00002'') //在SC中匹配 在 中匹配
4
for(int i =0; i<EOFout;i++) { for (int j = 0 ; j<EOFin;j++) }
5
使用EXISTS,首先检查主查询,然后运行 ,首先检查主查询, 使用 子查询直到它找到第一个匹配项, 子查询直到它找到第一个匹配项,这就节省 了时间。 了时间。 而执行IN子查询时 首先执行子查询, 子查询时, 而执行 子查询时,首先执行子查询,并将 获得的结果列表存放在一个加了索引的临时 表中。在执行子查询之前, 表中。在执行子查询之前,系统先将主查询 挂起,待子查询执行完毕, 挂起,待子查询执行完毕,存放在临时表中 以后再执行主查询。 以后再执行主查询。 因此,使用EXISTS比使用 通常查询速度 比使用IN通常查询速度 因此,使用 比使用 快。
13
回头看,就是我们第一个引出的题目 回头看,就是我们第一个引出的题目:
选修了全部课程的学生姓名
“选了全部课程的学生” 变成“找这样的 选了全部课程的学生” 变成“ 不存在一门课他没选的, 学生 :不存在一门课他没选的,也就是没 有课程他没有选 举一反三,请写出 举一反三 请写出
被全部学生都选的课程 被全部学生都不选的课程
11
思路二( 思路二(EXISTS) )
换个题目: 换个题目: 查找没有 没有选修科目的学生姓名 思路: 科目未知, 思路:学号未知 , 科目未知,说明有两个未知变 应该有两个EXISTS。 量。应该有两个 。 可以扫描student 和 course共有 s * c 中组合, 中组合, 可以扫描 共有 将这些组合与SC的每一项进行匹配 注意s*c组合 的每一项进行匹配, 将这些组合与 的每一项进行匹配,注意 组合 已经包含所有可能。 已经包含所有可能。如果全部找到 ,就说明已经 选修了全部课程。 选修了全部课程。找不到就说明有课程没选修 。 再将没选修的的提交给上一exists 循环 。若上一 再将没选修的的提交给上一 exists 不存在的再提交给外循环。 不存在的再提交给外循环。
9
思路二( 思路二(EXISTS) )
引入: 引入:将题目换为 查找学号为 00003 没有 选修的科目 思路: 思路:
将已知学号00003代入 代入 将已知学号 把每一个科目代入(循环) 把每一个科目代入(循环) 将上述两个条件组合,一一与SC表中的学号 表中的学号( 将上述两个条件组合,一一与 表中的学号( 00003 )和科目进行比对,找不到匹配的就是 和科目进行比对, 00003 没有选修的科目
3
建立程序循环的概念, 建立程序循环的概念,这是一个动态的查询 过程。 过程。如 FOR循环 。 循环 流程为首先取出外层中的第一个元组, 流程为首先取出外层中的第一个元组, 再 执行内层查询,将外层表的第一元组代入, 执行内层查询,将外层表的第一元组代入, 若内层查询为真,即有结果时, 若内层查询为真,即有结果时,返回外层表 接着取出第二元组, 中的第一元 组,接着取出第二元组,执行 相同的算法。 相同的算法。一直到扫描完外层整表 。
14
2、 查询至少选修了学生 、 查询至少选修了学生00002选修的全部课 选修的全部课 程的学生号码 它表示的语义为:不存在这样的课程 , 它表示的语义为:不存在这样的课程y,学 选了, 生95002选了,而学生 没有选 选了 而学生x没有选
15
select distinct sno from sc scx where not exists( select * from sc scy where sno='95002' and not exist( select * from sc scz where scz.sno = scx.sno and o=o))
专题:SQL之EXISTS
4
for(int i =0; i<EOFout;i++) { for (int j = 0 ; j<EOFin;j++) }
5
使用EXISTS,首先检查主查询,然后运行 子查询直到它找到第一个匹配项,这就节省 了时间。 而执行IN子查询时,首先执行子查询,并将 获得的结果列表存放在一个加了索引的临时 表中。在执行子查询之前,系统先将主查询 挂起,待子查询执行完毕,存放在临时表中 以后再执行主查询。 因此,使用EXISTS比使用IN通常查询速度 快。
12
思路二(EXISTS)
select Sname from student where NOT exists // (select * from course where NOT exists //不存在的提 //交给course (select * from SC where Sno = student.sno and cno = o) // 代//入 两个未知变量 )
select Sname from student where Sno IN (select Sno from SC group by Sno //根据Sno分组,统计每个 //学生选修了几门课程。如果等于course的 //总数,就是我们要找的Sno having count(*) = (select count(*) from course ) ) //统计course中共有几门课程
2
即:exists做为where 条件时,是先对 where 前的主查询进行查询,然后用主查询 的结果一个一个的代入exists的子查询进行 判断,如果为真则输出当前这一条主查询的 结果,否则不输出
3
建立程序循环的概念,这是一个动态的查询 过程。如 FOR循环 。 流程为首先取出外层中的第一个元组, 再 执行内层查询,将外层表的第一元组代入, 若内层查询为真,即有结果时,返回外层表 中的第一元 组,接着取出第二元组,执行 相同的算法。一直到扫描完外层整表 。
SQL中IN与EXISTS关键字
SQL中IN与EXISTS关键字 偶遇这样⼀个场景,使⽤IN关键字进⾏检索数据所消耗的时间是使⽤EXISTS关键字进⾏检索数据所消耗的时间的接近30倍。
⼀看差距这么⼤,查阅了⼀本SQL数据,其中也没有介绍多少,不过我们可以从其定义中可以领悟到⼀些差异。
(1)IN关键字:该操作符IN⽤于把⼀个值与⼀个指定列表进⾏⽐较,当被⽐较的值⾄少与列表中的⼀个值相匹配时,它会返回TRUE。
(2)EXISTS关键字:该操作符EXISTS⽤于搜索指定表⾥是否存在满⾜特定条件的记录。
根据这两个关键字作⽤的描述,可知:若是IN⼦句或者EXISTS⼦句都是采⽤SELECT语法检索出来的结果列表进⾏匹配的话,那么在IN⼦句中还要将被⽐较值与结果列表做进⼀步的循环⽐较,当IN中的被⽐较值能够匹配到结果列表中某个值,那么IN⼦句就会返回TRUE,否则的话就会返回FALSE;⽽在EXISTS⼦句中,若SELECT语句检索的结果值不为空,那么EXISTS⼦句直接将该结果集返回,若是检索的结果值为空的,那么EXISTS⼦句就返回空,也就是说EXISTS⼦句返回的就是SELECT语句返回的结果集,不需要再次做⽐较判断了。
-- INSELECT column1FROM table_nameWHERE some_col IN (SELECT column1 FROM table_name WHERE other_col >'xx');-- EXISTSSELECT column1FROM table_nameWHERE EXISTS (SELECT column1 FROM table_name WHERE other_col >'xx'); 上述代码⽰例只是⼀个象征性的对⽐说明,在同⼀个表中进⾏不同条件的多次检索,使⽤IN的⽅式:先根据条件检索出数据,然后some_col与结果列表进⾏循环⽐较;使⽤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 正好相反。
sql语言 exists语句的使用
用逻辑蕴函表达:查询学号为x的学生,对所有的课程y,只 要200215122学生选修了课程y,则x也选修了y。
形式化表示: 用P表示谓词 “学生200215122选修了课程y” 用q表示谓词 “学生x选修了课程y” 则上述查询为: (y) p q
带有EXISTS谓词的子查询(续)
由EXISTS引出的子查询,其目标列表达式通常都用* ,因 为带EXISTS的子查询只返回真值或假值,给出列名无实际 意义 2. NOT EXISTS谓词
若内层查询结果非空,则外层的WHERE子句返回假值 若内层查询结果为空,则外层的WHERE子句返回真值
带有EXISTS谓词的子查询(续)
带有EXISTS谓词的子查询(续)
查询选修了全部课程的学生姓名。
SELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno= Student.Sno AND Cno= o ) );
带有EXISTS谓词的子查询(续)
不同形式的查询间的替换
一些带EXISTS或NOT EXISTS谓词的子查询不能被其他形式 的子查询等价替换 所有带IN谓词、比较运算符、ANY和ALL谓词的子查询都能用 带EXISTS谓词的子查询等价替换
用EXISTS/NOT EXISTS实现全称量词(难点) SQL语言中没有全称量词 (For all) 可以把带有全称量词的谓词转换为等价的带有存在量词的谓词: (x)P ≡ ( x( P))
等价变换: (y)p q ≡ (y ((p q )) ≡ (y (( p∨ q) )) ≡ y(p∧q)
sql中exists用法循环 -回复
sql中exists用法循环-回复SQL中的exists用法与循环SQL(Structured Query Language)是一种专为管理关系型数据库管理系统(RDBMS)而设计的语言。
在SQL中,可以使用exists关键字来判断查询结果是否存在,从而进行相关的操作或逻辑的判断。
本文将逐步解析exists关键字的用法以及如何使用它进行循环操作。
第一步,了解exists关键字的作用和语法exists关键字用于判断是否存在满足某个条件的行。
它的语法为:SELECT 列名FROM 表名WHERE EXISTS (子查询);在这个语法中,exists后面的子查询返回的结果集如果不为空,则exists 返回的结果为真;否则为假。
第二步,使用exists关键字进行循环操作的实例现假设有两个表:学生表(students)和成绩表(scores)。
学生表包含学生的学号(id)和姓名(name),成绩表包含学生的学号(id)和语文成绩(chinese_score)。
我们需要根据成绩表中每个学生的语文成绩,判断该学生是否及格。
如果成绩大于等于60分,则标记为及格;否则标记为不及格。
首先,我们需要编写一个外层查询来选取学生表中的每一条记录:SELECT id, nameFROM students;然后,我们在exists子查询中编写对应的条件来判断成绩是否及格:SELECT id, nameFROM studentsWHERE EXISTS (SELECT *FROM scoresWHERE students.id = scores.idAND chinese_score >= 60);在这个子查询中,我们判断学生表的学号与成绩表的学号相等,并且判断语文成绩是否大于等于60分。
如果返回的结果集不为空,则表示该学生及格。
第三步,使用exists关键字进行循环操作的注意事项- 在SQL中,exists关键字通常用于子查询中,作为一个条件进行判断。
sql语句exists用法
sql语句exists用法SQL语句中的EXISTS用于判断子查询结果集是否存在,如果子查询有结果集,则返回True,否则返回False。
EXISTS可以用在Where、Having、Select子句中,一般与IN操作符、ANY/SOME操作符和ALL操作符配合使用,在某些情况下,EXISTS可以优化查询性能。
EXISTS用法详解EXISTS语法:sqlSELECT column_name(s)FROM table_name 1WHERE EXISTS(SELECT column_name FROM table_name 2 WHERE condition);上面的语法中,column_name是我们要检索的列名,table_name1是我们要搜索的表名,condition是我们要满足的任何条件,column_name和table_name2在它们的子查询中被使用。
实际上,EXISTS语句根据子查询返回的结果是否为空来确定是否返回结果集,如果子查询至少返回一行,则存在记录,即EXISTS条件成立;反之,则不存在记录,即EXISTS条件不成立。
例如,在一个包含客户信息和订单信息的数据表中,我们想筛选出购买了某些产品的客户,那么可以使用以下SQL语句:sqlSELECT * FROM customersWHERE EXISTS(SELECT * FROM orders WHEREcustomers.customer_id=orders.customer_idAND orders.product_id IN (‘9991’,’9832’,’3834’));上面这个SQL查询将检查customer_id等于客户表的orders.customer_id的订单表。
如果订单表中包含任何三种产品中的任何一种,则返回所有匹配的客户表行。
EXISTS与IN关系虽然EXISTS和IN的目的有所不同,但它们可以用相同的方式执行操作。
sql中exist 用法
sql中exist 用法
在SQL中,EXISTS是一个用于检查子查询结果是否为空的运算符。
它返回一个布尔值,如果子查询至少返回一行,则返回true,否则返回false。
EXIST的用法如下:
1. 使用EXISTS进行简单的子查询检查:
SELECT column1, column2,... FROM table1 WHERE EXISTS (SELECT column1 FROM table2 WHERE condition);
这个查询将检查table2中是否存在满足指定条件的行,如果存在,则返回table1中指定的列。
2. 使用EXISTS进行关联查询:
SELECT column1, column2,... FROM table1 WHERE EXISTS (SELECT column1 FROM table2 WHERE condition1 AND table1.column2 = table2.column2);
这个查询将根据指定条件和关联条件进行关联查询,只返回满足关联条件的行。
3. 使用EXISTS进行多级子查询:
SELECT column1, column2,... FROM table1 WHERE EXISTS (SELECT column1 FROM table2 WHERE condition1 AND EXISTS (SELECT column1 FROM table3 WHERE condition2)); 这个查询将使用多个子查询进行检查和关联,只返回满足所有
条件的行。
请注意,子查询中的SELECT语句可以是任意有效的SELECT语句,并且可以根据具体的需求来编写。
sql的存在函数
sql的存在函数存在函数(EXISTS)是结构化查询语言(SQL)中的一种条件函数,主要用于判断是否存在满足指定条件的行。
存在函数通常与子查询结合使用,它返回一个布尔值,表示子查询是否返回了一个以上的行。
如果子查询返回了至少一行结果,则存在函数返回TRUE;否则,返回FALSE。
语法:```SELECT column_name(s)FROM table_nameWHERE EXISTS (SELECT column_name(s) FROM table_name WHERE condition);```在使用存在函数时,需要注意以下几点:1. 子查询必须返回至少一行结果,否则存在函数将返回FALSE。
2. 子查询中的列可以是外部查询中的列,也可以是子查询中的一部分。
通常使用子查询的主键或外键列进行匹配。
3. 存在函数可以嵌套使用,多个嵌套的存在函数可以构建更复杂的查询条件。
存在函数在实际应用中有以下几个常见的应用场景。
1. 检查关联记录的存在性存在函数通常用于检查一个表中的记录是否存在于另一个表中。
比如,我们有一个"orders"表和一个"customers"表,我们可以使用存在函数来查找是否有与某个客户关联的订单:```SELECT customerNameFROM customersWHERE EXISTS (SELECT orderNumber FROM orders WHERE orders.customerID = customers.customerID);```上述查询将返回所有存在于"orders"表中的客户名称。
2. 检查子级数据的存在性有时候我们需要检查某个表中是否存在满足某个条件的子集。
例如,我们有一个"categories"表和一个"products"表,我们想要查找是否存在某个类别下有产品:```SELECT categoryNameFROM categoriesWHERE EXISTS (SELECT productID FROM products WHERE products.categoryID = categories.categoryID);```上述查询将返回所有有产品的类别名称。
sql中的exists用法
sql中的exists⽤法查询选修语⽂(cno=21)的学⽣名单SELECT sname FROM student WHERE EXISTS ( SELECT 1 FROM sc WHERE o = 21 AND sc.sno = student.sno )查询没有选修语⽂(cno=21)的学⽣名单SELECT sname FROM student WHERE NOT EXISTS ( SELECT 1 FROM sc WHERE o = 21 AND sc.sno = student.sno )选修全部课程的学⽣名单(⼦查询)SELECT sname FROM student WHERE sno in (SELECT sc.sno FROM sc GROUP BY sc.sno HAVING count(1) = (SELECT count(1) from course))选修全部课程的学⽣名单(exists)select * from student t where not exists( select * from course s where not exists(select * from sc where t.sno=sc.sno and o= o )) 当有课程没有选修时,下⾯的查询有返回的记录数。
当全部课程都选择时,返回空( select * from course s where not exists(select * from sc where t.sno=sc.sno and o= o ))数据库表结构--课程表CREATE TABLE `course` (`cno` int(11) NOT NULL DEFAULT '0',`cname` varchar(255) DEFAULT NULL,PRIMARY KEY (`cno`)) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;INSERT INTO `course` VALUES ('20', '数学');INSERT INTO `course` VALUES ('21', '语⽂');INSERT INTO `course` VALUES ('22', '外语');--课程学⽣表CREATE TABLE `sc` (`sno` int(11) NOT NULL DEFAULT '0',`cno` int(11) NOT NULL DEFAULT '0',PRIMARY KEY (`sno`,`cno`)) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;INSERT INTO `sc` VALUES ('10', '20');INSERT INTO `sc` VALUES ('10', '21');INSERT INTO `sc` VALUES ('11', '20');INSERT INTO `sc` VALUES ('11', '21');INSERT INTO `sc` VALUES ('11', '22');INSERT INTO `sc` VALUES ('12', '22');--学⽣表CREATE TABLE `student` (`sno` int(11) NOT NULL DEFAULT '0',`sname` varchar(255) DEFAULT NULL,PRIMARY KEY (`sno`)) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;INSERT INTO `student` VALUES ('10', 'zhangsan'); INSERT INTO `student` VALUES ('11', 'lisi'); INSERT INTO `student` VALUES ('12', 'wangwu');。
SQL之EXISTS用法示例
AND EXISTS(SELECT C.FID FROM T_SAL_OUTSTOCK C WHERE C.FID=B.FID AND CONVERT(VARCHAR(10),C.FDATE,120)>='2018-07-01'
FROM T_SAL_OUTSTOCKENTRY B WHERE A.FENTRYID=B.FENTRYID
AND EXISTS(SELECT FID FROM T_SAL_OUTSTOCKENTRY_R C WHERE C.FID=B.FID AND C.FSRCBILLNO LIKE 'CA%' AND EXISTS(SELECT FID FROM T_SAL_OUTSTOCK D WHERE D.FID=C.FID AND CONVERT(VARCHAR(10),D.FDATE,120)>='2018-07-01' ) )
更新表信息嵌套exists最内层大范围筛选修改日期的fid信息次内层进一步筛选符合调拨单的fid信息嵌套外层筛选符合fid条件的分录内码fentryid信息updateasetafamountlc0afprice0fromtsaloutstockentrycawhereexistsselectfentryidfromtsaloutstockentrybwhereafentryidbfentryidandexistsselectfidfromtsaloutstockentryrcwherecfidbfidandcfsrcbillnolikecaandexistsselectfidfromtsaloutstockdwheredfidcfidandconvertvarchar10dfdate12020180701
