create table t_class(
c_id int primary key,
c_name varchar(10)
);
insert into t_class values(1,'一班');
insert into t_class values(2,'二班');
insert into t_class values(3,'三班');
alter table 学生表 add c_id int;
--流程
select *,0 as 人数 from t_class;
select *,
(
select count(*) from 学生表 s
where s.c_id=c.c_id
) as 人数
from t_class c;
--循环:c.c_id为1,2,3,分别代入子查询,子查询再执行
--理解:
执行外部查询
select * from t_class
c_id c_name
1 一班
select count(*) from 学生表 s where s.c_id=1
2 二班
select count(*) from 学生表 s where s.c_id=2
3 三班
select count(*) from 学生表 s where s.c_id=3
效率:非常低,应该尽量避免(使用表连接)
但是知识点(相关子查询)是非常重要的!
子查询不能单独运行:
select count(*) from 学生表 s
where s.c_id=c.c_id
非相关子查询是可以的:
select max(score) from t_score
语法:
查询哪些班上没有人
select *
from t_class c
where not exists(
select * from 学生表 s where s.c_id=c.c_id
)
唯一一个where后面不需要指明字段的
子查询中select的值没有限制
select *
from t_class c
where not exists(
select 'x' from 学生表 s where s.c_id=c.c_id
)
语法:
from 表1
where [not] exists
( select * from 表2 where 表2.id=表1.id)
流程同上:先执行外部查询,外部查询返回的每一行,子查询分别执行一次
select * from t_class c
返回:
1 一班
select * from 学生表 s where s.c_id=1
有2行数据返回 → 证明存在 →不满足 not exists→不显示
(只需要返回其中一条即可证明→由exists的核心算法决定)
2 二班
select * from 学生表 s where s.c_id=2
分析同上。
3 三班
select * from 学生表 s where s.c_id=3
无数据返回→证明 不存在→满足not exists→显示
思考:为什么子查询返回的数据不需要限制?
并不在乎返回的是什么数据,而在乎有没有数据返回
select * from 学生表 s where s.c_id=2
效果等价于
select 1,'x' from 学生表 s where s.c_id=2
查询不存在时,有一个简单的方法:not in
select * from t_class c
where c_id not in (select distinct c_id from 学生表)
如果子查询返回多行数据,必须用in,如果返回一行,才能用=,>,!=等
select * from t_class c
where c_id = (select distinct c_id from 学生表)
错误:子查询返回的值多于一个
逻辑:用=只能等于一个值,现在有多个值,所以不能用=,应该用in