MySQL子查询

【图书推荐】《MySQL 9从入门到性能优化(视频教学版)》-CSDN博客

《MySQL 9从入门到性能优化(视频教学版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com)

MySQL9数据库技术_夏天又到了的博客-CSDN博客

子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL 4.1开始引入。在SELECT子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一张表或者多张表。子查询中常用的操作符有ANY(SOME)、ALL、IN、EXISTS。子查询可以添加到SELECT、UPDATE和DELETE语句中,而且可以进行多层嵌套。子查询中也可以使用比较运算符,如"<""<="">"">="和"!="等。本节将介绍如何在SELECT语句中嵌套子查询。

5.5.1 带ANY、SOME关键字的子查询

ANY和SOME是同义词,表示满足其中任意一个条件。它们允许创建一个表达式对子查询的返回值列表进行比较,只要满足内层子查询中的任何一个比较条件,就返回一个结果作为外层查询的条件。

下面定义两张表tbl1和tbl2:

复制代码
CREATE table tbl1 ( num1 INT NOT NULL);
CREATE table tbl2 ( num2 INT NOT NULL);

分别向两张表中插入数据:

复制代码
INSERT INTO tbl1 values(1), (5), (13), (27);
INSERT INTO tbl2 values(6), (14), (11), (20);

ANY关键字接在一个比较操作符的后面,表示若与子查询返回的任何值比较的结果为TRUE,则返回TRUE。

【例5.53】返回表tbl2中的num2列的所有值,然后将表tbl1中的num1列的值与num2列的值进行比较,只要num1列中的值大于num2列中的任何一个值,即为符合查询条件的结果。

复制代码
mysql> SELECT num1 FROM tbl1 WHERE num1 > ANY (SELECT num2 FROM tbl2);
+------+
| num1 |
+------+
|   13 |
|   27 |
+------+

在子查询中,返回的是表tbl2的num2列的值,即(6,14,11,20),然后将表tbl1中的num1列的值与(6,14,11,20)进行比较,只要num1列中的值大于(6,14,11,20)中的任意一个,即为符合条件的结果,因此返回的结果为(13,27)。

5.5.2 带ALL关键字的子查询

ALL关键字与ANY和SOME不同,使用ALL时需要同时满足所有内层查询的条件。

ALL关键字接在一个比较操作符的后面,表示与子查询返回的所有值进行比较,若结果为TRUE,则返回TRUE。

下面修改【例5.53】,用ALL关键字替换ANY。

【例5.54】返回表tbl1中比表tbl2的num2列所有值都大的值,SQL语句如下:

复制代码
mysql> SELECT num1 FROM tbl1 WHERE num1 > ALL (SELECT num2 FROM tbl2);
+------+
| num1 |
+------+
|   27 |
+------+

在子查询中,返回的是表tbl2的值,即num2列的所有(6,14,11,20),然后将表tbl1中的num1列的值与之进行比较,大于所有num2列值的num1值只有27,因此返回结果为27。

5.5.3 带EXISTS关键字的子查询

EXISTS关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,那么EXISTS返回的结果为TRUE,此时外层查询语句将进行查询;如果子查询没有返回任何行,那么EXISTS返回的结果是FALSE,此时外层查询语句将不进行查询。

【例5.55】查询表suppliers中是否存在s_id=107的水果供应商,如果存在,则查询表fruits中的记录,SQL语句如下:

复制代码
mysql> SELECT * FROM fruits WHERE EXISTS (SELECT s_name FROM suppliers WHERE s_id = 107);
+------+-------+-----------+---------+
| f_id | s_id  | f_name    | f_price |
+------+-------+-----------+---------+
| a1   |  101  | apple     |    5.20 |
| a2   |  103  | apricot   |    2.20 |
| b1   |  101  | blackberry|   10.20 |
| b2   |  104  | berry     |    7.60 |
| b5   |  107  | xxxx      |    3.60 |
| bs1  |  102  | orange    |   11.20 |
| bs2  |  105  | melon     |    8.20 |
| c0   |  101  | cherry    |    3.20 |
| l2   |  104  | lemon     |    6.40 |
| m1   |  106  | mango     |   15.70 |
| m2   |  105  | xbabay    |    2.60 |
| m3   |  105  | xxtt      |   11.60 |
| o2   |  103  | coconut   |    9.20 |
| t1   |  102  | banana    |   10.30 |
| t2   |  102  | grape     |    5.30 |
| t4   |  107  | xbababa   |    3.60 |
+------+------+------------+---------+

由结果可以看到,内层查询结果表明表suppliers中存在s_id=107的记录,因此EXISTS表达式返回TRUE;外层查询语句接收TRUE之后对表fruits进行查询,返回所有的记录。

EXISTS关键字可以和条件表达式一起使用。

【例5.56】查询表suppliers中是否存在s_id=107的水果供应商,如果存在,则查询表fruits中的f_price>10.20的记录,SQL语句如下:

复制代码
mysql> SELECT * FROM fruits WHERE f_price>10.20 AND EXISTS  (SELECT s_name FROM suppliers WHERE s_id = 107);
+------+------+--------+---------+
| f_id | s_id | f_name | f_price |
+------+------+--------+---------+
| bs1  |  102 | orange |   11.20 |
| m1   |  106 | mango  |   15.70 |
| m3   |  105 | xxtt   |   11.60 |
| t1   |  102 | banana |   10.30 |
+------+------+--------+---------+

由结果可以看到,内层查询结果表明表suppliers中存在s_id=107的记录,因此EXISTS表达式返回TRUE;外层查询语句接收TRUE之后根据查询条件f_price > 10.20对表fruits进行查询,返回结果为4条f_price>10.20的记录。

NOT EXISTS与EXISTS的使用方法相同,返回的结果相反。子查询如果至少返回一行,那么NOT EXISTS返回的结果为FALSE,此时外层查询语句将不进行查询;如果子查询没有返回任何行,那么NOT EXISTS返回的结果是TRUE,此时外层查询语句将进行查询。

【例5.57】查询表suppliers中是否存在s_id=107的水果供应商,如果不存在,则查询表fruits中的记录,SQL语句如下:

复制代码
mysql> SELECT * FROM fruits WHERE NOT EXISTS  (SELECT s_name FROM suppliers WHERE s_id = 107);
Empty set (0.00 sec)

查询语句SELECT s_name FROM suppliers WHERE s_id = 107对表suppliers进行查询并返回了一条记录,因此NOT EXISTS表达式返回FALSE,外层表达式接收FALSE,将不再查询表fruits中的记录。

相关推荐
存在的五月雨7 小时前
Mysql 索引的一些
数据库·mysql
黄俊懿7 小时前
MySQL主从复制:从“异步“到“GTID“,数据同步的进化之路
数据库·sql·mysql·oracle·架构·dba·db
看海的四叔8 小时前
【SQL】SQL-管好你的字符串
大数据·数据库·hive·sql·数据分析·字符串
秋98 小时前
TiDB 数据库全链路实战指南:从下载部署到 Java 高并发调优
java·数据库·tidb
zhou周大哥8 小时前
银河麒麟安装mysql
数据库·mysql
无敌的黑星星8 小时前
Spring @Transactional 注解全解析
java·数据库·oracle
Rust研习社9 小时前
Rust + PostgreSQL 极简技术栈应用开发
开发语言·数据库·后端·http·postgresql·rust
河阿里9 小时前
MyBatis-Plus:MyBatis的进阶开发
数据库·mybatis
sjsjsbbsbsn9 小时前
向量数据库
数据库
逸Y 仙X9 小时前
文章十六:ElasticSearch 使用enrich策略实现大宽表
java·大数据·数据库·elasticsearch·搜索引擎·全文检索