添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
MySQL约束、函数和运算符
8 MySQL操作表中数据
8.1 MySQL查询数据表
8.2 MySQL去重
8.3 MySQL设置别名
8.4 MySQL限制查询结果的条数
8.5 MySQL对查询结果排序
8.6 MySQL条件查询
8.7 MySQL使用LIKE模糊查询
8.8 MySQL范围查询
8.9 MySQL空值查询
8.10 MySQL分组查询
8.11 MySQL过滤分组
8.12 MySQL交叉连接
8.13 MySQL内连接
8.14 MySQL外连接
8.15 MySQL子查询
8.16 MySQL子查询注意事项
8.17 MySQL子查询的简单改写优化
8.18 MySQL正则表达式查询
8.19 SQL查询语句先执行SELECT?兄弟你认真的么?
8.20 MySQL插入数据
8.21 MySQL修改数据
8.22 MySQL删除数据
8.23 MySQL清空表记录
8.24 MySQL如何多表关联更新?
8.25 MySQL如何处理无效数据值?
8.26 向MySQL发送一个请求的时候,MySQL到底做了些什么?
8.27 不得不说的SQL注入攻击,别一不留神就被利用了!
MySQL视图、索引 MySQL存储过程和触发器 MySQL事务和字符集 MySQL用户管理 MySQL数据库备份与恢复 MySQL日志 MySQL性能优化
前面我们介绍了如何使用 SELECT、INSERT、UPDATE 和 DELETE 语句对 MySQL 进行简单访问和操作。下面在此基础上开始学习子查询。
子查询是 MySQL 中比较常用的查询方法,通过子查询可以实现多表查询。 子查询指将一个查询语句嵌套在另一个查询语句中。 子查询可以在 SELECT、UPDATE 和 DELETE 语句中使用,而且可以进行多层嵌套。在实际开发时,子查询经常出现在 WHERE 子句中。
子查询在 WHERE 中的语法格式如下: WHERE <表达式> <操作符> (子查询)

其中,操作符可以是比较运算符和 IN、NOT IN、EXISTS、NOT EXISTS 等关键字。
1)IN | NOT IN 当表达式与子查询返回的结果集中的某个值相等时,返回 TRUE,否则返回 FALSE;若使用关键字 NOT,则返回值正好相反。 2)EXISTS | NOT EXISTS 用于判断子查询的结果集是否为空,若子查询的结果集不为空,返回 TRUE,否则返回 FALSE;若使用关键字 NOT,则返回的值正好相反。
使用子查询在 tb_students_info 表和 tb_course 表中查询学习 Java 课程的学生姓名,SQL 语句和运行结果如下。 mysql> SELECT name FROM tb_students_info -> WHERE course_id IN (SELECT id FROM tb_course WHERE course_name = 'Java'); +-------+ | name | +-------+ | Dany | | Henry | +-------+ 2 rows in set (0.01 sec) 结果显示,学习 Java 课程的只有 Dany 和 Henry。上述查询过程也可以分为以下 2 步执行,实现效果是相同的。
1)首先单独执行内查询,查询出 tb_course 表中课程为 Java 的 id,SQL 语句和运行结果如下。 mysql> SELECT id FROM tb_course -> WHERE course_name = 'Java'; +----+ | id | +----+ | 1 | +----+ 1 row in set (0.00 sec) 可以看到,符合条件的 id 字段的值为 1。
2)然后执行外层查询,在 tb_students_info 表中查询 course_id 等于 1 的学生姓名。SQL 语句和运行结果如下。 mysql> SELECT name FROM tb_students_info -> WHERE course_id IN (1); +-------+ | name | +-------+ | Dany | | Henry | +-------+ 2 rows in set (0.00 sec) 习惯上,外层的 SELECT 查询称为父查询,圆括号中嵌入的查询称为子查询( 子查询必须放在圆括号内 )。MySQL 在处理上例的 SELECT 语句时,执行流程为: 先执行子查询,再执行父查询
与例 1 类似,在 SELECT 语句中使用 NOT IN 关键字,查询没有学习 Java 课程的学生姓名,SQL 语句和运行结果如下。 mysql> SELECT name FROM tb_students_info -> WHERE course_id NOT IN (SELECT id FROM tb_course WHERE course_name = 'Java'); +--------+ | name | +--------+ | Green | | Jane | | Jim | | John | | Lily | | Susan | | Thomas | | Tom | | LiMing | +--------+ 9 rows in set (0.01 sec) 可以看出,运行结果与例 1 刚好相反,没有学习 Java 课程的是除了 Dany 和 Henry 之外的学生。

使用 = 运算符,在 tb_course 表和 tb_students_info 表中查询出所有学习 Python 课程的学生姓名,SQL 语句和运行结果如下。 mysql> SELECT name FROM tb_students_info -> WHERE course_id = (SELECT id FROM tb_course WHERE course_name = 'Python'); +------+ | name | +------+ | Jane | +------+ 1 row in set (0.00 sec) 结果显示,学习 Python 课程的学生只有 Jane。
使用 <> 运算符,在 tb_course 表和 tb_students_info 表中查询出没有学习 Python 课程的学生姓名,SQL 语句和运行结果如下。 mysql> SELECT name FROM tb_students_info -> WHERE course_id <> (SELECT id FROM tb_course WHERE course_name = 'Python'); +--------+ | name | +--------+ | Dany | | Green | | Henry | | Jim | | John | | Lily | | Susan | | Thomas | | Tom | | LiMing | +--------+ 10 rows in set (0.00 sec) 可以看出,运行结果与例 3 刚好相反,没有学习 Python 课程的是除了 Jane 之外的学生。
查询 tb_course 表中是否存在 id=1 的课程,如果存在,就查询出 tb_students_info 表中的记录,SQL 语句和运行结果如下。 mysql> SELECT * FROM tb_students_info -> WHERE EXISTS(SELECT course_name FROM tb_course WHERE id=1); +----+--------+------+------+--------+-----------+ | id | name | age | sex | height | course_id | +----+--------+------+------+--------+-----------+ | 1 | Dany | 25 | 男 | 160 | 1 | | 2 | Green | 23 | 男 | 158 | 2 | | 3 | Henry | 23 | 女 | 185 | 1 | | 4 | Jane | 22 | 男 | 162 | 3 | | 5 | Jim | 24 | 女 | 175 | 2 | | 6 | John | 21 | 女 | 172 | 4 | | 7 | Lily | 22 | 男 | 165 | 4 | | 8 | Susan | 23 | 男 | 170 | 5 | | 9 | Thomas | 22 | 女 | 178 | 5 | | 10 | Tom | 23 | 女 | 165 | 5 | | 11 | LiMing | 22 | 男 | 180 | 7 | +----+--------+------+------+--------+-----------+ 11 rows in set (0.01 sec) 由结果可以看到,tb_course 表中存在 id=1 的记录,因此 EXISTS 表达式返回 TRUE,外层查询语句接收 TRUE 之后对表 tb_students_info 进行查询,返回所有的记录。
EXISTS 关键字可以和其它查询条件一起使用,条件表达式与 EXISTS 关键字之间用 AND 和 OR 连接。
查询 tb_course 表中是否存在 id=1 的课程,如果存在,就查询出 tb_students_info 表中 age 字段大于 24 的记录,SQL 语句和运行结果如下。 mysql> SELECT * FROM tb_students_info -> WHERE age>24 AND EXISTS(SELECT course_name FROM tb_course WHERE id=1); +----+------+------+------+--------+-----------+ | id | name | age | sex | height | course_id | +----+------+------+------+--------+-----------+ | 1 | Dany | 25 | 男 | 160 | 1 | +----+------+------+------+--------+-----------+ 1 row in set (0.01 sec) 结果显示,从 tb_students_info 表中查询出了一条记录,这条记录的 age 字段取值为 25。内层查询语句从 tb_course 表中查询到记录,返回 TRUE。外层查询语句开始进行查询。根据查询条件,从 tb_students_info 表中查询 age 大于 24 的记录。
子查询的功能也可以通过表连接完成,但是子查询会使 SQL 语句更容易阅读和编写。
一般来说,表连接(内连接和外连接等)都可以用子查询替换,但反过来却不一定,有的子查询不能用表连接来替换。子查询比较灵活、方便、形式多样,适合作为查询的筛选条件,而表连接更适合于查看连接表的数据。

关注公众号「 站长严长生 」,在手机上阅读所有教程,随时随地都能学习。内含一款搜索神器,免费下载全网书籍和视频。

微信扫码关注公众号