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

相关推荐
乙龙15 分钟前
麒麟V10系统上安装Oracle
数据库·oracle·ffmpeg
m0_748247801 小时前
如何使用C#与SQL Server数据库进行交互
数据库·c#·交互
m0_748240761 小时前
开源模型应用落地-CodeQwen模型小试-SQL专家测试(二)
数据库·sql·开源
kiwixing2 小时前
DM达梦启用及收集AWR报告
数据库·database·达梦·数据库架构
m0_748233883 小时前
MySQL(七)MySQL和Oracle、PostgreSQL的区别
mysql·postgresql·oracle
莳花微语4 小时前
Oracle ADG 主备切换新旧语法对比
数据库·oracle
driftingman4 小时前
CloudberryDB(四)并行执行
数据库·分布式·postgresql
贤时间4 小时前
Oracle graph 图数据库体验-安装篇
数据库·oracle
然然阿然然4 小时前
2025.1.15——五、时间盲注
数据库·安全·web安全·网络安全
m0_748240254 小时前
【Python系列】Python 连接 PostgreSQL 数据库并查询数据
数据库·python·postgresql