二十、子查询

1、子查询的定义及分类

定义: 子查询(sub query)是指总的查询是在某个结果之上进行的查询,即是一条select语句内部包含了另外一条select语句。
分类的方法: 子查询可以按照两种方式进行分类,分别为按子查询语句在外部查询语句的位置分类、按子查询查询的结果分类;
按照子查询语句的位置分类:

  1. from子查询:子查询跟在from之后
  2. where子查询:子查询跟在where之后
  3. exists子查询:子查询跟在exists之后

按查询结果分类:

  1. 标量子查询:子查询得到的结果是一行一列
  2. 列子查询:子查询得到的结果是一列(一列多行)
  3. 行子查询:子查询得到的结果是一行(一行多列)
    注: 以上几个子查询出现的位置在where之后
  4. 表子查询:子查询得到的结果是多行多列(出现的位置在from之后)

上面就是关于子查询分类及定义的一些介绍,下面将会针对各种子查询进行较为详细的介绍。

2、标量子查询

我们通过一个例子来看标量子查询的语法等信息。
首先,先用下列SQL语句建立相关数据表

//建立班级表
  create table if not exists class(
    id tinyint primary key auto_increment,
    cname varchar(10)
  );
//插入数据
  insert into class(cname) values('python班'),
  ('java班'),
  ('AI班'),
  ('linux班');
//建立老师表
  create table if not exists head_master(
     id tinyint primary key auto_increment,
     tname varchar(10),
     c_id tinyint,
     constraint c_id foreign key(c_id) references class(id)
  );
//插入数据
  insert into head_master(tname,c_id) values('刘天一',1),
  ('悬空',2),('李志毅',3),('黄华基',4);

然后看下面例子
例:知道班级名字为’python班’,想获取该班的班主任信息
解析:

   //确定数据源,该结果的数据源肯定来自于老师表
   select * from head_master where c_id = ?;
   //确定名字为"python班"的班级id
   select id from class where c_name = 'python班';
   //综合上述两个语句
   select * from head_master where c_id = (select id from class where cname = 'python班');   

子查询得到的结果为一列一行:
在这里插入图片描述
上述语句执行结果如下:
在这里插入图片描述

3、列子查询

同“2”,先看一个例子:
查询班级名称为“python班”、“AI班”、“linux班”的班主任信息
解析:

//先确定数据源(因为是查询班主任信息,所以肯定是要从head_master表中找)
select * from head_master where c_id = ?;
//确定条件(即是确定问号处的内容,也就是要根据班级名称找出班级id,必须要在class表中找)
select id from class where cname in ('python班','AI班','linux班');
//综合上述两个语句,得到最终的查询语句
select * from head_master where c_id in 
(select id from class where cname in ('python班','AI班','linux班'));

作为子查询的查询结果(即第二条查询语句的结果):
在这里插入图片描述
最终的查询结果如下:
在这里插入图片描述

4、行子查询

展示行子查询的例子:查询整个学生中年龄最大并且身高最高的学生

   //主查询
   select * from student having age = (?) and height = (?);
   //确定最大年龄和最大身高
   select max(age) from student;
   select max(height) from student;
   //将上述的三个语句进行合并
   select * from student having 
   age = (select max(age) from student) 
   and height = (select max(height) from student);
   //再对上述语句进行处理,形成真正的行子查询
   select * from my_student where (age,height)=(select max(age),max(height) from my_student);

注: 上述语句中(age,height)称为行元素

5、表子查询

定义: 子查询返回的结果是多行多列的二维表,更多的是因为子查询返回的结果是当做二维表来使用的。
实例: 找出每个班中最高的一个学生

//先将总体学生按照身高从高到底的顺序排序
select * from student order by height desc;
//从每个班选出第一个学生
select * from student group by c_id;
--表子查询:from子查询 得到的结果作为from的数据源
//综合上述语句,形成此题解答
select * from (select * from student order by height desc) s group by c_id;

注意! 上述最后的语句绝对不能写成“select * from student group by c_id order by height;”;因为这条语句是先从表中取出数据,然后按照c_id进行分组,并且取每组的第一个数据,最后进行排序,然后进行显示,而不是先将每个班级的排序,再进行分组。

6、exists子查询

exists关键字解析: 是否存在的意思,exists子查询就是用来判断某些条件是否满足,exists子句经常接在where之后,其返回的结果只有0和1;
对于exists关键字返回结果的证明:

//1、
select exists (select * from head_master);
//2、
select exists (select * from head_master where id = 10);

结果1、
在这里插入图片描述
结果2、
在这里插入图片描述
实例: 只要有班级存在,就查询所有的学生
select * from student where exists (select c_id from class);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值