专题:SQL之EXISTS
- 格式:ppt
- 大小:311.50 KB
- 文档页数:16
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的⽤法⽐如在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用法循环-回复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用于判断子查询结果集是否存在,如果子查询有结果集,则返回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中,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的存在函数存在函数(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⽤法查询选修语⽂(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');。
exists用法sql
在SQL中,`EXISTS`是用于检查子查询返回的结果集是否为空的关键字。
`EXISTS`通常与`WHERE`子句一起使用,用于过滤查询结果。
它的语法如下:
```sql
SELECT column1, column2, ...
FROM table
WHERE EXISTS (subquery)
```
在`EXISTS`后面的括号中,可以使用子查询来指定一个条件。
如果子查询返回的结果集非空,那么`EXISTS`的条件为真,否则为假。
下面是一个示例,使用`EXISTS`查找具有某种特定特征的记录: ```sql
SELECT emp_name
FROM employees
WHERE EXISTS (
SELECT emp_id
FROM departments
WHERE employees.emp_id = departments.emp_id
AND department_name = "Finance"
)
```
在这个例子中,`EXISTS`用于检查是否存在一个具有部门名称为"Finance"的记录。
如果存在,那么该员工的姓名将被返回。
请注意,`EXISTS`只关心子查询返回的结果集是否为空,而不关心实际返回的数据是什么。
因此,子查询可以包含任何有效的SQL语句,只要它返回一个结果集即可。
sql中exists的用法SQL中的EXISTS语句是一种非常重要的查询方式,它用于判断一个子查询是否返回任何结果,如果存在,则返回TRUE,否则,返回FALSE。
这个方法为我们提供了一种在查询中过滤数据的有效手段,让我们能够更加精确地获取需要的结果。
在本文中,我们将深入探讨EXISTS语句,包括语法,用法和示例。
我们将覆盖以下主题:1. EXISTS语句的语法2. EXISTS语句的使用方法3. EXISTS语句的实际应用1. EXISTS语句的语法EXISTS语句的语法如下:```sqlSELECT column1, column2, ... column_nFROM table_nameWHERE EXISTS (subquery);```在上面的语法中,我们需要使用SELECT语句选择从表中获取的列,FROM子句指定要查询的表,WHERE子句中的EXISTS子句是包含条件的子查询。
我们可以与EXISTS一起使用NOT运算符来判断查询的子查询返回的结果是否为空,这里的语法为:```sqlSELECT column1, column2, ... column_nFROM table_nameWHERE NOT EXISTS (subquery);```在下面的示例中,我们将使用上述语法来讲解EXISTS语句更具体的细节。
2. EXISTS语句的使用方法现在,我们将介绍如何使用EXISTS语句进行数据查询。
为了更好的说明,我们将使用下面的两个表作为示例:1. employee表| emp_id | emp_name | emp_salary ||--------|----------|------------|| 101 | John | 5000 || 102 | Smith | 6000 || 103 | Jane | 7000 || 104 | James | 8000 || 105 | Michael | 9000 |2. department表| dept_id | dept_name ||---------|-----------|| 001 | IT || 002 | HR || 003 | Sales || 004 | Marketing |要使用EXISTS语句,我们需要构建一个子查询,并将其放在WHERE子句中。
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中EXISTS用法EXISTS 是判断是否存在,和in类似,但效率要比in高SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X'FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB')SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB')这两句效果一样EXISTS或者NOT EXISTS是把主查询的字段传到后边的查询中作为条件,返回值是TRUE或者FALSE。
EXISTS TRUE,那么就是查询条件成立,结果会显示出来。
NOT EXISTS TRUE,则为FALSE,查询连接条件不成立。
select * from course where not exists(select * from grade where grade.课程代号=course.课程代号)这个语句,是查询course表中课程代号在grade中没有出现的数据。
看看grade表,课程编号有K01到K06,而COURSE表,有K01到K07,那么K07在GRADE表是不存在的,那么,是符合条件的。
同样select * from course where exists(select * from grade where grade.课程代号=course.课程代号)则是查询COURSE的记录条件为编号在GRADE中存在。
那么很明显,结果是K01到K06的数据。
另外,EXISTS和NOT EXISTS的作用可以用IN或NOT IN实现,但是,效率要高。
因为EXISTS和NOT EXISTS返回的结果是TRUE或者FALSE,那么则在子查询中,遇到第一个符合条件的结果,就会退出查询,而不会进行全表的检索。
sql exists用法
EXISTS 是SQL语言中的一种运算符,其作用是判断子查询是否返回任何行,如果返
回则结果为“True”,反之为”False”。
EXISTS 常用于子查询中,它返回子查询是否返
回任何的记录值,如果子查询返回任何行,则EXISTS 会返回true,否则,返回false。
EXISTS 常用于SELECT 或者 UPDATE 语句中, WHERE 条件也可以选择。
EXISTS 用在SELECT 中的语句如下:
SELECT *
FROM 表A
WHERE EXISTS(SELECT 1 FROM 表 B WHERE 表A.字段A = 表B.字段A)
上面的例子表示:从表A查询出符合条件的行,条件是子查询从表B中返回的行的字
段A的值和表A的字段A的值相同。
即从表A中获取:字段A的值在表B 中存在的行。
还有许多用法,但必须记住,EXISTS操作符仅供返回布尔值(True 或False),它
不会返回实际的行。
通过使用 EXISTS,可以在 WHERE 子句中组合出更复杂的 SQL 语句。
sql中exist的用法
exist是一种用于判断子查询是否返回结果的函数。
其语法为:EXISTS(subquery)。
如果subquery返回至少一行结果,则exist返
回true,否则返回false。
在sql中,exist常常与关键词IN或NOT IN搭配使用,例如: SELECT *
FROM Table1
WHERE EXISTS (
SELECT *
FROM Table2
WHERE Table1.key = Table2.key
);
这个查询将返回Table1表中的所有行,其中key列的值存在于Table2表中的key列中。
在实际应用中,exist可以用于优化sql语句的性能。
由于exist 只判断子查询是否返回结果,而不会返回实际结果集,因此对于大型数据集和复杂查询,使用exist可以减少查询的开销和提高查询效率。
总之,exist是sql中一个非常实用的函数,可以用于判断子查询是否返回结果并优化查询的性能。
- 1 -。
SQL进阶系列之8EXISTS谓词的⽤法写在前⾯⽀撑SQL和关系数据库的基础理论:数学领域的集合论和逻辑学标准体系的谓词逻辑理论篇什么是谓词?谓词是返回值为真值(true false unknown)的函数关系数据库⾥,每⼀个⾏数据可以看作是⼀个命题实体的阶层0阶实体(单⾏) -- 1阶谓词( = between and)1阶实体(⾏集合/表) -- 2阶谓词 (exists)2阶实体(表的集合) -- 3阶谓词 1970被毙掉,⽬前数据库均以⼆阶谓词为基准全称量化与存在量化全称量词:所有的x都满⾜条件P存在量词:存在(⾄少有⼀个)满⾜条件P的xEXISTS谓词实现了存在量词(因此,可以根据德摩根律实现全称量化)实践篇查询表中不存在的数据/* 查询表中“不”存在的数据 */CREATE TABLE Meetings(meeting CHAR(32) NOT NULL,person CHAR(32) NOT NULL,PRIMARY KEY (meeting, person));INSERT INTO Meetings VALUES('第1次', '伊藤');INSERT INTO Meetings VALUES('第1次', '⽔岛');INSERT INTO Meetings VALUES('第1次', '坂东');INSERT INTO Meetings VALUES('第2次', '伊藤');INSERT INTO Meetings VALUES('第2次', '宫⽥');INSERT INTO Meetings VALUES('第3次', '坂东');INSERT INTO Meetings VALUES('第3次', '⽔岛');INSERT INTO Meetings VALUES('第3次', '宫⽥');-- 求所有⼈参加所有会的笛卡尔积SELECT DISTINCT m1.meeting,m2.person FROM Meetings AS m1 CROSS JOIN Meetings AS m2;-- 求出缺席者的SQL语句(1):存在量化的应⽤SELECT DISTINCT m1.meeting,m2.personFROM Meetings AS m1 CROSS JOIN Meetings AS m2WHERE NOT EXISTS (SELECT * FROM Meetings AS m3 WHERE m1.meeting = m3.meeting AND m2.person = m3.person);-- 求出缺席者的SQL语句(2):使⽤差集运算SELECT m1.meeting,m2.personFROM Meetings AS m1,Meetings AS m2EXCEPTSELECT meeting,personFROM Meetings;全称量词(1):习惯"肯定\Leftrightarrow双重否定"之间的转换/* 全称量化(1):习惯“肯定<=>双重否定”之间的转换 */CREATE TABLE TestScores(student_id INTEGER,subject VARCHAR(32) ,score INTEGER,PRIMARY KEY(student_id, subject));INSERT INTO TestScores VALUES(100, '数学',100);INSERT INTO TestScores VALUES(100, '语⽂',80);INSERT INTO TestScores VALUES(100, '理化',80);INSERT INTO TestScores VALUES(200, '数学',80);INSERT INTO TestScores VALUES(200, '语⽂',95);INSERT INTO TestScores VALUES(300, '数学',40);INSERT INTO TestScores VALUES(300, '语⽂',90);INSERT INTO TestScores VALUES(300, '社会',55);INSERT INTO TestScores VALUES(400, '数学',80);-- 查出所有科⽬分数都在50分以上的学⽣SELECT DISTINCT student_id FROM TestScores AS TS1WHERE NOT EXISTS (SELECT * FROM TestScores AS TS2 WHERE TS2.student_id= TS1.student_id AND TS2.score < 50) -- 仅就本题⽽⾔,还可以使⽤min(score)>=50-- 查找出数学分数>=80,语⽂分数>=50的学⽣SELECT DISTINCT student_id FROM TestScores AS TS1WHERE subject IN ('数学','语⽂') AND NOT EXISTS (SELECT * FROM TestScores AS TS2 WHERE TS2.student_id= TS1.student_id AND 1 = CASE WHEN subject = '数学' AND score < 80 THEN 1WHEN subject = '语⽂' AND score < 50 THEN 1 ELSE 0 END)GROUP BY student_idHAVING COUNT(*) = 2; -- group by having ⼦句要求两门课程都要有成绩全称量化(2):集合和谓词,哪个更强⼤?/* 全称量化(2):集合VS谓词——哪个更强⼤? */CREATE TABLE Projects(project_id VARCHAR(32),step_nbr INTEGER ,status VARCHAR(32),PRIMARY KEY(project_id, step_nbr));INSERT INTO Projects VALUES('AA100', 0, '完成');INSERT INTO Projects VALUES('AA100', 1, '等待');INSERT INTO Projects VALUES('AA100', 2, '等待');INSERT INTO Projects VALUES('B200', 0, '等待');INSERT INTO Projects VALUES('B200', 1, '等待');INSERT INTO Projects VALUES('CS300', 0, '完成');INSERT INTO Projects VALUES('CS300', 1, '完成');INSERT INTO Projects VALUES('CS300', 2, '等待');INSERT INTO Projects VALUES('CS300', 3, '等待');INSERT INTO Projects VALUES('DY400', 0, '完成');INSERT INTO Projects VALUES('DY400', 1, '完成');INSERT INTO Projects VALUES('DY400', 2, '完成');-- 查询完成到了⼯程1的项⽬ having⼦句解法SELECT product_id FROM Projects GROUP BY project_id HAVING COUNT(*) = SUM(CASE WHEN step_nbr <= AND status = '完成' THEN 1 WHEN step_nbr > 1 AND status = '等待' THEN 1 ELSE 0 END); -- 查询完成到了⼯程1的项⽬ having⼦句解法谓词解法SELECT * FROM Projects P1 WHERE NOT EXISTS (SELECT status from Projects P2 WHERE P1.project_id = P2.project_id AND status <> CASE WHEN step_nbr <= 1 THEN '完成' ELSE '等待' END);-- 劣势:双重否定,不易理解;优势:性能好,只要有⼀个⾏满⾜条件,查询就会终⽌;包含的信息更全对列进⾏量化:查询全是1的⾏/* 对列进⾏量化:查询全是1的⾏ */CREATE TABLE ArrayTbl(keycol CHAR(1) PRIMARY KEY,col1 INTEGER,col2 INTEGER,col3 INTEGER,col4 INTEGER,col5 INTEGER,col6 INTEGER,col7 INTEGER,col8 INTEGER,col9 INTEGER,col10 INTEGER);--全为NULLINSERT INTO ArrayTbl VALUES('A', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);INSERT INTO ArrayTbl VALUES('B', 3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);--全为1INSERT INTO ArrayTbl VALUES('C', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);--⾄少有⼀个9INSERT INTO ArrayTbl VALUES('D', NULL, NULL, 9, NULL, NULL, NULL, NULL, NULL, NULL, NULL);INSERT INTO ArrayTbl VALUES('E', NULL, 3, NULL, 1, 9, NULL, NULL, 9, NULL, NULL);-- "列⽅向"的全称量化:查找全是1的⾏不优雅的解答SELECT * FROM ArrayTbl WHERE col1 = 1 AND col2 = 1 AND col3 = 1 AND col4 = 1 AND col5 = 1AND col6 = 1 AND col7 = 1 AND col8 = 1 AND col9 = 1 AND col10 = 1;-- "列⽅向"的全称量化:查找全是1的⾏优雅的解答SELECT * FROM ArrayTbl WHERE 1 = ALL (values(col1),(col2),(col3),(col4),(col5),(col6),(col7),(col8),(col9),(col10));-- "列⽅向"的全称量化:查找某⼀列是9的⾏SELECT * FROM ArrayTbl WHERE 9 = ANY (values(col1),(col2),(col3),(col4),(col5),(col6),(col7),(col8),(col9),(col10));-- "列⽅向"的全称量化:查找某⼀列是9的⾏SELECT * FROM ArrayTbl WHERE 9 IN (col1,col2,col3,col4,col5,col6,col7,col8,col9,col10);-- 查找全是NULL的⾏SELECT * FROM ArrayTbl WHERE COALESCE(col1,col2,col3,col4,col5,col6,col7,col8,col9,col10) IS NULL;⼩结SQL中的谓词指的是返回真值的函数EXISTS与其他谓词不同,接受的参数是集合因此EXISTS可以看成⼀种⾼阶函数SQL没有与全称量词相当的谓词,可以使⽤NOT EXISTS代替练习题/* 练习题1-8-1:数组表——⾏结构表的情况 */CREATE TABLE ArrayTbl2(key CHAR(1) NOT NULL,i INTEGER NOT NULL,val INTEGER,PRIMARY KEY (key, i));/* A全为NULL、B仅有⼀个为⾮NULL、C全为⾮NULL */INSERT INTO ArrayTbl2 VALUES('A', 1, NULL);INSERT INTO ArrayTbl2 VALUES('A', 2, NULL);INSERT INTO ArrayTbl2 VALUES('A', 3, NULL);INSERT INTO ArrayTbl2 VALUES('A', 4, NULL);INSERT INTO ArrayTbl2 VALUES('A', 5, NULL);INSERT INTO ArrayTbl2 VALUES('A', 6, NULL);INSERT INTO ArrayTbl2 VALUES('A', 7, NULL);INSERT INTO ArrayTbl2 VALUES('A', 8, NULL);INSERT INTO ArrayTbl2 VALUES('A', 9, NULL);INSERT INTO ArrayTbl2 VALUES('A',10, NULL);INSERT INTO ArrayTbl2 VALUES('B', 1, 3);INSERT INTO ArrayTbl2 VALUES('B', 2, NULL);INSERT INTO ArrayTbl2 VALUES('B', 3, NULL);INSERT INTO ArrayTbl2 VALUES('B', 4, NULL);INSERT INTO ArrayTbl2 VALUES('B', 5, NULL);INSERT INTO ArrayTbl2 VALUES('B', 6, NULL);INSERT INTO ArrayTbl2 VALUES('B', 7, NULL);INSERT INTO ArrayTbl2 VALUES('B', 8, NULL);INSERT INTO ArrayTbl2 VALUES('B', 9, NULL);INSERT INTO ArrayTbl2 VALUES('B',10, NULL);INSERT INTO ArrayTbl2 VALUES('C', 1, 1);INSERT INTO ArrayTbl2 VALUES('C', 2, 1);INSERT INTO ArrayTbl2 VALUES('C', 3, 1);INSERT INTO ArrayTbl2 VALUES('C', 4, 1);INSERT INTO ArrayTbl2 VALUES('C', 5, 1);INSERT INTO ArrayTbl2 VALUES('C', 6, 1);INSERT INTO ArrayTbl2 VALUES('C', 7, 1);INSERT INTO ArrayTbl2 VALUES('C', 8, 1);INSERT INTO ArrayTbl2 VALUES('C', 9, 1);INSERT INTO ArrayTbl2 VALUES('C',10, 1);/* 正确解法 */SELECT DISTINCT keyFROM ArrayTbl2 A1WHERE NOT EXISTS(SELECT *FROM ArrayTbl2 A2WHERE A1.key = A2.keyAND (A2.val <> 1 OR A2.val IS NULL));/* 其他解法1:使⽤ALL谓词 */SELECT DISTINCT keyFROM ArrayTbl2 A1WHERE 1 = ALL(SELECT valFROM ArrayTbl2 A2WHERE A1.key = A2.key);/* 其他解法2:使⽤HAVING⼦句 */SELECT keyFROM ArrayTbl2GROUP BY keyHAVING SUM(CASE WHEN val = 1 THEN 1 ELSE 0 END) = 10;/* 其他解法3:在HAVING⼦句中使⽤极值函数 */SELECT keyFROM ArrayTbl2GROUP BY keyHAVING MAX(val) = 1AND MIN(val) = 1;/* 练习题1-8-2:使⽤ALL谓词进⾏全称量化查找已经完成到⼯程1的项⽬:使⽤ALL谓词解答 */SELECT *FROM Projects P1WHERE '○' = ALL(SELECT CASE WHEN step_nbr <= 1 AND status = '完成' THEN '○'WHEN step_nbr > 1 AND status = '等待' THEN '○'ELSE '×' ENDFROM Projects P2WHERE P1.project_id = P2. project_id);/* 练习题1-8-3:求(1-100)中的质数 */SELECT num AS primeFROM Numbers DividendWHERE num > 1AND NOT EXISTS(SELECT *FROM Numbers DivisorWHERE Divisor.num <= Dividend.num / 2 /* 除了⾃⾝之外的约数必定⼩于等于⾃⾝值的⼀半 */ AND Divisor.num <> 1 /* 约数中不包含1 */AND MOD(Dividend.num, Divisor.num) = 0) /*“除不尽”的否定条件是“除尽” */ORDER BY prime;Processing math: 0%。
sql中exists,notexists的⽤法exists : 强调的是是否返回结果集,不要求知道返回什么, ⽐如:select name from student where sex = 'm' and mark exists(select 1 from grade where ...) ,只要exists引导的⼦句有结果集返回,那么exists这个条件就算成⽴了,⼤家注意返回的字段始终为1,如果改成“select 2 from grade where ...”,那么返回的字段就是2,这个数字没有意义。
所以exists⼦句不在乎返回什么,⽽是在乎是不是有结果集返回。
⽽ exists 与 in 最⼤的区别在于 in引导的⼦句只能返回⼀个字段,⽐如:select name from student where sex = 'm' and mark in (select 1,2,3 from grade where ...),in⼦句返回了三个字段,这是不正确的,exists⼦句是允许的,但in只允许有⼀个字段返回,在1,2,3中随便去了两个字段即可。
⽽not exists 和not in 分别是exists 和 in 的对⽴⾯。
exists (sql 返回结果集为真) not exists (sql 不返回结果集为真)下⾯详细描述not exists的过程:如下:表AID NAME 1 A12 A23 A3表BID AID NAME1 1 B12 2 B2 3 2 B3表A和表B是1对多的关系 A.ID => B.AIDSELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHEREA.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)执⾏结果为3A3===========================================================================EXISTS = IN,意思相同不过语法上有点点区别,好像使⽤IN效率要差点,应该是不会执⾏索引的原因SELECTID,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)有时候我们会遇到要选出某⼀列不重复,某⼀列作为选择条件,其他列正常输出的情况.如下⾯的表table:Id Name Class Count Date1 苹果⽔果 10 2011-7-11 桔⼦⽔果 20 2011-7-21 ⾹蕉⽔果 15 2011-7-32 ⽩菜蔬菜 12 2011-7-12 青菜蔬菜 19 2011-7-2如果想要得到下⾯的结果:(Id唯⼀,Date选最近的⼀次)1 ⾹蕉⽔果 15 2011-7-32 青菜蔬菜 19 2011-7-2正确的SQL语句是:SELECT Id, Name, Class, Count, DateFROM table tWHERE (NOT EXISTS(SELECT Id, Name, Class, Count, Date FROM tableWHERE Id = t.Id AND Date > t.Date))如果⽤distinct,得不到这个结果, 因为distinct是作⽤与所有列的SELECT DISTINCT Id, Name, Class, Count, Date FROM table结果是表table的所有不同列都显⽰出来,如下所⽰:1 苹果⽔果 10 2011-7-11 桔⼦⽔果 20 2011-7-21 ⾹蕉⽔果 15 2011-7-32 ⽩菜蔬菜 12 2011-7-12 青菜蔬菜 19 2011-7-2如果⽤Group by也得不到需要的结果,因为Group by 要和聚合函数共同使⽤,所以对于Name,Class和Count列要么使⽤Group by,要么使⽤聚合函数. 如果写成SELECT Id, Name, Class, Count, MAX(Date)FROM tableGROUP BY Id, Name, Class, Count得到的结果是1 苹果⽔果 10 2011-7-11 桔⼦⽔果 20 2011-7-21 ⾹蕉⽔果 15 2011-7-32 ⽩菜蔬菜 12 2011-7-12 青菜蔬菜 19 2011-7-2如果写成SELECT Id, MAX(Name), MAX(Class), MAX(Count), MAX(Date)FROM tableGROUP BY Id得到的结果是:1 ⾹蕉⽔果 20 2011-7-32 青菜蔬菜 19 2011-7-2如果⽤in有时候也得不到结果,(有的时候可以得到,如果Date都不相同(没有重复数据),或者是下⾯得到的Max(Date)只有⼀个值)SELECT DISTINCT Id, Name, Class, Count, Date FROM tableWHERE (Date IN(SELECT MAX(Date)FROM tableGROUP BY Id))得到的结果是:(因为MAX(Date)有两个值2011-7-2,2011-7-3)1 桔⼦⽔果 20 2011-7-21 ⾹蕉⽔果 15 2011-7-32 青菜蔬菜 19 2011-7-2注意in只允许有⼀个字段返回有⼀种⽅法可以实现:SELECT Id, Name, Class, COUNT, DateFROM table1 tWHERE (Date = (SELECT MAX(Date) FROM table1 WHERE Id = t .Id))⽐如在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 指定⼀个⼦查询,检测⾏的存在。
sql 中exists用法SQL中exists用法在SQL中,exists是一个非常有用的关键字,用于检查一个子查询是否至少返回一行结果。
exists通常与主查询的where子句一起使用,以确定特定条件是否成立。
exists的语法如下:```SELECT column1, column2, ...FROM table1WHERE EXISTS (subquery);```在子查询中,我们可以根据需求使用各种条件和语句。
exists语句将返回true或false,取决于子查询是否返回任何行。
exists语句非常适合以下场景:1. 存在性检查:用于检查特定条件下是否存在符合要求的数据行。
例如,我们需要查询存在未支付订单的客户。
```SELECT customer_nameFROM customersWHERE EXISTS (SELECT * FROM orders WHEREcustomers.customer_id = orders.customer_id AND orders.status = 'unpaid');```在这个例子中,子查询用于检查是否存在未支付的订单。
如果存在任何未支付的订单,exists将返回true,并包含具有未支付订单的客户的名称。
2. 子查询过滤:可以使用exists关键字作为过滤条件来限制主查询返回的结果集。
例如,我们需要查询所有至少拥有一辆汽车的客户。
```SELECT customer_id, customer_nameFROM customersWHERE EXISTS (SELECT * FROM cars WHEREcustomers.customer_id = cars.customer_id);```在这个例子中,子查询用于过滤掉没有拥有任何汽车的客户。
只有存在相关汽车的客户才会被包含在结果集中。
3. 避免重复行:在某些情况下,我们可能需要避免返回重复的数据行。