教程集 www.jiaochengji.com
教程集 >  数据库  >  mysql  >  正文 mysql中子查询学习笔记

mysql中子查询学习笔记

发布时间:2023-04-29   编辑:jiaochengji.com
教程集为您提供mysql中子查询学习笔记等资源,欢迎您收藏本站,我们将为您提供最新的mysql中子查询学习笔记资源
当一个查询是另一个查询的条件时,称之为子查询。子查询可以使用几个简单命令构造功能强大的复合命令。

子查询最常用于SELECT-SQL命令的WHERE子句中。
子查询是一个 SELECT 语句,它嵌套在一个 SELECT、SELECT...INTO 语句、INSERT...INTO 语句、DELETE 语句、或 UPDATE 语句或嵌套在另一子查询中

子查询可以写在WHERE子句、HAVING子句、FROM子句中。
子查询分为多行子查询和单行子查询。

如果能够保证返回的行数小于等于1行的,则是单行子查询。
使用单行比较操作符:=、>、>=、<、<=、<>。
否则是多行子查询。
使用多行比较符:IN、> ANY 、> ALL、< ANY、< ALL。
下面我们测试下子查询的效果,还是用之前的TEST_T表。表结构查询一般情况下返回一个列的值(单列子查询),也可以返回多个列的值(多列子查询),但要成对匹配。
单列子查询可以在DECODE和CASE语句,还有SELECT中除GROUP BY子句以外的所有子句中使用。
多列子查询例子:

select t1.id 序号, t1.no 班级, t1.s_name 学生名字, t1.score 分数 from test_t t1 where (t1.id,t1.score) in (select t2.id, t2.score from test_t t2);

这里子查询返回两个列,但外层查询也要同时匹配这两个列。

单列子查询例子:
--查找表中分数最高的学生的名字和班级

select no 班级, s_name 学生名字 from test_t where score in(select max(score) from test_t);

班级 学生名字
2 李四
3 小C

关联子查询:
关联子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。
--查找每个班级中分数最高的学生的班级、名字和分数
为了测试的准确性,再插入一条记录:

INSERT INTO TEST_T (ID, NO, T_NAME, S_NAME, SCORE) VALUES ('10', '2', 'Mary', 'AAA', '70');

思路一(使用关联子查询):

select t1.id 序号, t1.no 班级, t1.s_name 学生名字, t1.score 分数 from test_t t1 where t1.score = (select max(t2.score) from test_t t2 where t1.no = t2.no);

查询结果:

序号 班级 学生名字 分数
2 2 李四 99
7 1 Zhang 70
6 3 小C 99

该句使用了关联子查询,内层查询用t1.no = t2.no和外层查询的字段做匹配。
关联子查询的执行过程(猜测):
1)先从外层查询的test_t t1表取出一行

ID NO T_NAME S_NAME SCORE
1 1 Peter 张三 60

2)到内层查询中t2表筛选t1.no = t2.no(把同一个班级的记录都筛选出来,返回了这个班级的最高分)

ID NO T_NAME S_NAME SCORE
1 1 Peter 张三 60
4 1 Peter 小A 59
7 1 Peter Zhang 70

返回了70这个值
3)外层比较score是否和t2.score相等,这里是不等,于是返回空
4)外层查询继续取下一条记录,继续循环
如果t1.no = t2.no判断条件放到外层查询中:

select t1.id 序号, t1.no 班级, t1.s_name 学生名字, t1.score 分数 from test_t t1 where t1.score = (select max(t2.score) from test_t t2) and t1.no = t2.no;

就会报错ORA-00904: "T2"."NO": 标识符无效
说明对于非关联子查询,外层查询看不到内层查询使用的表,因为此时内层查询已经返回结果了。

思路二(使用group by):

select id 序号, no 班级, s_name 学生名字, score 分数 from test_t where (no,score) in(select no 班级, max(score) 分数 from test_t group by no);

使用多列子查询,先在内层查询用班级号分组,算出最高分,返回给外层查询

 

exists和not exists关键字
exists操作符检查在子查询中是否存在满足条件的行。exists只返回true或false。
exists和关联子查询:
1、如果在子查询中存在满足条件的行:
如果能找到一行,对于这个子查询来说,不继续查找,exists返回true。
继续下一个子查询。
2、如果在子查询中不存在满足条件的行:
如果没有一行满足子查询条件,子查询的查询结果为空,exists返回false。
继续下一个子查询。
因为exists只返回true或false,所以在子查询中select后面只要写成select 1就行了。

TEST_T表。

select * from test_t t1 where exists (select 1 from test_t t2 where t2.score < 60 and t1.id = t2.id);

ID NO T_NAME S_NAME SCORE
4 1 Peter 小A 59

1)从主查询里取出一行,到子查询查找满足score < 60 and t1.id = t2.id的行
2)子查询只要找到一条满足条件的行,exists返回true,输出主查询的这一行
3)如果子查询结果为空,exists返回false,则不输出主查询的这一行
not exists关键字
没有满足条件的行,返回true。
有满足条件的行,返回false。
如果子查询的结果都为空,那么会返回主查询的所有行。

select * from test_t t1 where not exists (select 1 from test_t t2 where t2.score < 90 and t1.id = t2.id);

ID NO T_NAME S_NAME SCORE
6 3 Tom 小C 99
2 2 Mary 李四 99
9 3 Tom Li 90

您可能感兴趣的文章:
MySQL子查询的学习小结
mysql取随机数据的方法
影响MySQL性能的查询类型有哪些
分享:mysql随机查询若干条数据的方法
mysql随机查询大量数据的sql语句性能分析
mysql打开慢查询日志的方法
mysql中子查询学习笔记
mysql多表联合查询并返回一张表的内容的sql代码
mysql 分页查询的sql语句
mysql where in 用法举例

[关闭]
~ ~