对于下表,
1. 场景:查询代课天数最多的老师的信息。
方法一:select % from teacher order by days desc limit 1 ;
该方法有漏洞:授课天数最多的老师实际上有两位:Hanna和Luna。
直接设置limit 1会限制只输出1位老师。而实际我们不知道有几个代课最多的老师,不知道怎么设置 limit。
【改进】分两步完成:
第一步:先获得代课天数最多的天数:select max(days) from teacher ;
第二步:再判断哪个老师的代课天数与最大值是相同的。
MySQL允许将第一步的查询结果作为一个值保存起来使用:
var1 = select max(days) from teacher;
select * from teacher where days = var1 ;
以上两句相当于 select * from teacher where days = (select max(days) from teacher) ;
【定义】如果一个查询语句出现在另一个语句(不一定是查询语句)内部,则第一个语句称为子查询。
要求:子查询语句必须使用括号。
优点:可以将目标拆分成几步。
2. 分类标准(不同的分类,会有不同的使用方式)。
① 子查询出现的位置。
· where 型:出现在where后; · from 型:出现在 from 后; · exists 型:出现在exists 后。
② 子查询的返回值形式。
· 单一值: · 一列: · 多列: · 表(多行多列)。
3. 如何使用。
① 标量子查询。
② 列子查询(使用集合类的操作符完成 in | not in | any | all | some)。
【举个栗子】检索所有带过‘php0228’班的老师们带过的班级信息。
【分析】第一步:select t_name from teacher where c_name='php0228';
第二步:select t_name,c_name,days from teacher where t_name in (select t_name from teacher where c_name='php0228');
tip: = any 相当于 in; != all 相当于 not in
③ 返回一行(limit 1):
【举个栗子】查找带过0331班,与Linda具有相同代课天数的老师。
【分析】select t_name,gender,c_name from teacher where (gender,c_name)=(select gender,c_name from teacher where t_name='Linda' and c_name='php0331');
以上称为“行子查询”,不太常用。
④ 返回一个表:
select * from (select t_name,c_name,days from teacher where days>15) as temp ;
若只写到(子查询语句),则返回的是多行,需要给这几行命名,用 as+【临时名称】即可。
tip: 关键字 as 可以用来起别名,例如 select t_name as teach from teacher ;//相当于给t_name起了别名teach。
⑤ exists 子查询。
使用方法:exists(子查询语句)
判断依据:若子查询可以返回数据,则认为exists表发誓返回真;
否则,返回假。