目录
1.IN/NOT IN子查询
从执行结果中可以看出,出错的原因是"Subquery returns more than 1 row",也就是说,出错的原因是子查询返回了多于1行的结果。为什么子查询返回多于1行的结果时SQL语句会执行错误?这个原因在前面高级一中介绍子查询的时候提到过,这里再次予以强调。
在使用比较运算符时,要求子查询只能返回1条或空的记录。也就是说,在MySQL中,当子查询跟随在<、>、=、<=、>=、!=之后时,子查询的返回结果不能是多条记录;否则将会出错。那么,出现了这样的问题应该如何解决?解决的方法就是本次将要介绍的IN关键字,将"="替换为"IN"即可。
1.NOT IN子查询
IN子查询将结果集中多条数据作为匹配条件,在实际开发过程中,还存在匹配结果集以外数据的情况。这种查询应该如何实现呢?很简单,在IN关键字前加上表示否定的NOT即可,也就是NOT IN子查询。
2.EXISTS/NOT EXISTS子查询
我们在学习使用SQL语句创建数据库或数据表时使用了EXISTS关键字,用它来判断数据库或数据表是否存在,以决定是否执行创建数据库或数据表的操作。实际上EXISTS和NOT EXISTS关键字也可以用于子查询。
在学习EXISTS子查询前,首先回顾EXISTS在建库建表或删库删表语句中的使用方法。以删除patient_address表为例,使用EXISTS判断patient_address表是否存在,若存在,则删除。关键代码如下。
DROP TABLE IF EXISTS patient_address;
在执行CREATE或DROP语句前,EXISTS语句判断该数据库对象是否已经存在,EXIOSTS的返回值是true或false,根据EXISTS的返回值决定是否执行数据库操作语句。EXISTS的另一种用法是在WHERE语句中作为子查询使用。语法格式如下。
SELECT ······FROM 表名 WHERE EXISTS(子查询);
EXISTS在WHERE子句中作为子查询使用时,若子查询的查询结果中有数据,则EXISTS子查询的结果为true,其外层查询语句会被执行。若子查询的查询结果中没有数据,则EXISTS子查询的结果为false,其外层查询语句不会被执行。
EXISTS子查询的作用是检测是否存在符合查询条件的记录,然后根据业务逻辑查询符合要求的相应记录。
和IN子查询一样,EXISTS子查询也允许添加 NOT关键字实现相反的操作,NOT EXISTS子查询表示结果集中不存在记录时返回true,否则返回false。
3.子查询总结
进入信息时代,人们处于海量数据中,业务需求越来越复杂,这就对开发人员提出更高的要求。开发人员不仅要熟练掌握对数据表中的数据执行增、删、改操作和简单的SQL语句查询,还要根据客户的实际需求使用子查询语句从多张表中查询获取相关数据。
1.子查询知识回顾
当一个查询是另一个查询的条件时,被称为子查询。子查询可以使用几个简单的查询语句构成功能强大的复合查询语句。在编写子查询语句时,需求注意以下事项。
- 子查询语句必须放在"()"中。
- 子查询语句出现的位置很灵活。
子查询常用于SELECT的WHERE子句中。子查询是一个SELECT语句,可以嵌套在一个SELECT、SELECT······INTO语句、INSERT······INTO语句、DELETE语句、UPDATE语句中或嵌套在另一子查询中。
除SELECT的WHERE子句可以嵌套子查询外,子查询还可以嵌套于SELECT语句的列、表和查询条件中,即SELECT子句、GROUP BY子句和HAVING子句。但是ORDER BY子句中不能嵌套子查询。下面介绍子查询经常在SQL语句中出现的位置。
1.在SELECT子句的子查询
在SELECT子句中进行子查询的语法格式如下。
SELECT(子查询)[AS 列别名] FROM 表名;
此时子查询的结果必须为单行单列,其中,列别名为可选项。
2.在FROM子句中的子查询
在FROM子句中进行查询的语法格式如下。
SELECT * FROM (子查询) AS 表别名;
此时子查询的结果一般为多行多列,可以当作一张临时表,而且必须为子查询的结果指定表别名。
常见错误:
SELECT * FROM (SELECT * FROM prescription);
这类错误的产生原因就是没有为子查询的查询结果指定别名。正确的写法如下。
SELECT * FROM (SELECT * FROM prescription) AS temp;
代码中的别名可以任意取,没有特殊的要求,通常将子查询语句放在比较条件的右边以增加可读性,子查询可以返回单行或多行数据,此时要选择合适的关键字。
- 子查询返回单行数据时,比较条件中可以使用比较运算符。
- 子查询返回多行数据时,比较条件中需要使用IN或NOT IN关键字。
- 当判断子查询是否有数据返回时,需要使用EXISTS或NOT EXISTS关键字。
- 只出现在子查询中但是没有出现在父查询中的表不能包含在输出列中。
- 子查询的输出结果通常作为其外层子查询的数据源或用于数据判断匹配,而不能作为最外层SELECT子句的输出字段。
4.总结
- 在开发过程中,若判断结果集可以为多条数据,则使用IN子查询能够避免语句执行错误。
- EXISTS和NOT EXISTS子查询的结果只取决于查询有无结果而与其具体的内容无关。
- 除SELECT的WHERE子句中可以嵌套子查询外,子查询还可以嵌套于SELET语句的列、表和查询条件中,即SELECT子句、GEOUP BY子句和HAVING子句。
- ORDER BY子句中不能嵌套查询。
- 只出现在子查询中但是没有出现在父查询中的表不能包含在输出列中。