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中的记录。

相关推荐
百***920211 小时前
【MySQL】MySQL库的操作
android·数据库·mysql
q***766611 小时前
Spring Boot 从 2.7.x 升级到 3.3注意事项
数据库·hive·spring boot
信仰_27399324311 小时前
Redis红锁
数据库·redis·缓存
人间打气筒(Ada)12 小时前
Centos7 搭建hadoop2.7.2、hbase伪分布式集群
数据库·分布式·hbase
心灵宝贝12 小时前
如何在 Mac 上安装 MySQL 8.0.20.dmg(从下载到使用全流程)
数据库·mysql·macos
想睡hhh12 小时前
mysql索引——理解索引机制及操作
mysql
剑动山河12 小时前
ubuntu 升级mysql由mysql5.7.42 升级到8.4.0
mysql·ubuntu·adb
奋斗的牛马13 小时前
OFDM理解
网络·数据库·单片机·嵌入式硬件·fpga开发·信息与通信
忧郁的橙子.13 小时前
一、Rabbit MQ 初级
服务器·网络·数据库
杰杰79814 小时前
SQL 实战:用户访问 → 下单 → 支付全流程转化率分析
数据库·sql