MySQL 10.子查询

子查询

​ 子查询是出现在其他语句中的 select 语句,内部嵌套 select 语句的查询,叫做外查询或主查询

结果集可能的情况:

  • 标量子查询(单行子查询):结果集只有一行一列
  • 列子查询(多行子查询):结果集只有一列多行
  • 行子查询:结果集只有一行多列
  • 表子查询:结果集通常为多行多列

子查询出现的位置:

  • select 后面:仅支持标量子查询
  • from 后面:支持表子查询
  • where 或 having 后面:标量子查询、列子查询、行子查询
  • exists 后面(相关子查询):表子查询

特点:

  • 子查询写在 () 内,通常放在条件的后面
  • 子查询的执行优先于主查询,主查询的条件用到了子查询返回的结果

where 或 having 中的子查询

标量子查询
  • 标量子查询通常搭配单行操作符使用:>、<、>=、<=、=、<>
  • 非法使用标量子查询:指子查询的结果不是一行一列,即结果无法与单行操作符进行操作
(1).where
-- 查询 classid 与 A 相同, score 比 B 高的所有 student
select classid
from student
where name = 'A';
-- 查询指定 student 的 classid

select score
from student
where name = 'B';
-- 查询指定 student 的 score

select name,score,classid
from student 
where classid = (
    select classid
    from student 
    where name = 'A'
)
and score > (
    select score
    from student
    where name = 'B'
);

(2).having
-- 查询最低 score 大于 class3 的最低 score 的 classid 和其最低 score
select min(score)
from student 
-- 查询 class3 的最低 score

select classid,min(score)
from student
group by classid
having min(score) > (
    select min(score)
    from student
);

select calssid,avg(score)
from student 
group by classid

(3).查询每个 class 中 score 高于本 avg(score) 的 student
select *
from student s 
where s.score > (
    select avg(score) a
    from student 
    group by classid
    having s.classid = student.classid)
order by classid,score desc;
列子查询
  • 列子查询通常搭配多行操作符使用:in、any/some、all
  • in 等价于 =any() ,not in 等价于 != all
  • 比任意低/高使用 any,比所有低/高使用 all
操作符 含义
in / not in 等于列表中的任意一个
any / some 和子查询返回的某一个值比较
all 和子查询返回的所有值比较
(1).in
-- 查询 avg(score) 大于 x 的 class 和其中所有 student
select classid
from student 
group by classid
having avg(score) >= 72.5;
-- 查询 avg(score) 大于 72.5 的class

select name,score 
from student
where classid in (
    select classid
    from student
    group by classid
    having avg(score) >= 72.5
);

(2).any、some / all
-- 查询其他 class 中,比 class2 任意/所有 score 低的 student 和其 score
select distinct score
from student
where classid = 2;
-- 查询 class2 中所有出现过的 score

select name,classid,score
from student
where classid != 2
and score < any(
    select distinct score
    from student
    where classid = 2
);
行子查询
select *
from student
where (字段1,字段2) = (
    select min(字段1),max(字段2)
    from student
)

select 中的子查询

  • 仅支持标量子查询
select c.*,(
    select count(*) 
    from student s
    where s.classid = c.id
) 
from class c;

from 中的子查询

  • 把子查询的结果集当成一张新的表
  • 新的表必须设置别名
select classid,avg(score)
from student 
group by classid;
-- 查询每个 class 的 avg(score)

select * from score_level
-- 查询 score_level 表

select a_s.*,l.name
from (
    select classid,avg(score) a
    from student 
    group by classid) a_s
inner join score_level l
on a_s.a between l.min_score and l.max_score;

exists 中的子查询(相关子查询)

-- 查询参数中是否有值,结果为0或1
exists(完整的查询语句)
(1).使用 exists 实现
select *
from class c
where exists(
    select *
    from student s
    where s.classid = c.id
);

(2).使用 in 实现 exists 
select *
from class c
where c.id in (
    select s.classid
    from student s
);
上一篇:突破:量子计算机首次实现简化逻辑门


下一篇:顺序结构及if用法