子查询: 将一条sql查询语句作为中间结果,供另外一条查询语句使用, 这个中间结果查询就是子查询(sql嵌套).
作用:
原本需要执行多条sql完成的事情,如果通过子查询只需要执行一条sql, 这样可以简化执行步骤.(代码中的步骤)
案例: 查询学生信息,要求学生年龄小于全部学生的平均年龄.-- a.查询全部学生平均年龄selectavg(age)as avg from student;# 45-- b. 查询大于平均年龄的学生select*from student where age <45;-- c. 通过子查询实现select*from student where age <(selectavg(age)as avg from student);
子查询的分类:
1.按位置分:
1.1where 型子查询: 子查询出现在where子句中
select*from student where age <(selectavg(age)as avg from student);
1.2from 型子查询: 子查询出现在from子句中
注意实现:
1. 如果子查询出现在from子句中, 相当于一个临时表(派生表), 需要取一个别名;
案例: 查询学生表中的年龄排前5的学生, 要求结果是按照年龄升序排列.-- a 查询学生表中的年龄排前5的学生select*from student orderby age desclimit0,5;-- b 结果是按照年龄升序排列select*from(select*from student orderby age desclimit0,5)as t orderby age asc;
2.按结果分:
2.1.列子查询: 子查询结果为一列多行
说明: 列子查询其实返回的是一个集合,判断使用 in 或者 notin
案例: 查询没有学生的 班级信息
select*from class where class_id notin(selectdistinct class_id from student where class_id isnotnull);-- 经验: 逆向思维-- 先查询有学生的 班级信息
a. 查询学生表中的班级id(有班级id就说明有学生)selectdistinct class_id from student where class_id isnotnull;
b. 根据查询到的班级id到班级表中查询班级信息
select*from class where class_id in(1,2,3);
c. 子查询形式
select*from class where class_id in(selectdistinct class_id from student where class_id isnotnull);
2.2.行子查询: 子查询结果为一行多列
说明:
需要使用 小括号() 行构建符, 将多个字段的值构建成一行, 与行子查询的结果做对比.-- 案例: 请问学生中是否有班级id最大且年龄也最大的学生?
a. 查询班级id最大的值和年龄最大的值
selectmax(class_id),max(age)from student;
b. 根据以上结果再查询学生信息
select*from student where class_id=3and age =100;
c. 子查询形式实现
select*from student where(class_id,age)=(selectmax(class_id),max(age)from student)
2.3.表子查询: 子查询结果为多行多列
-- 案例: 查询每个班中年龄最大的学生的信息.
a. 分组查询每个班中年龄最大的值
select class_id,max(age)as max from student where class_id isnotnullgroupby class_id;
b. 根据以上结果 再查询学生的信息
select*from student
where(class_id,age)in(select class_id,max(age)as max from student where class_id isnotnullgroupby class_id)(1,40)in[(1,40),(2,45),(3,50)]