概述
子查询是SQL查询中的重要一块,是我们基于多表之间进行数据聚合和判断的一种手段,使得我们的处理复杂数据更加的便捷,这一节我们主要来了解一下子查询。
先做一下数据准备,这边建立三张表:班级、学生、毕业成绩表,用于后面的操作:
drop database if exists `Helenlyn_Class`;
create database `Helenlyn_Class`;
/*班级表*/
DROP TABLE IF EXISTS `classes`;
CREATE TABLE `classes` (
`classid` int primary key AUTO_INCREMENT comment '班级id',
`classname` varchar(30) DEFAULT NULL comment '班级名称'
) ENGINE=InnoDB comment '班级表';
insert into `classes`(`classname`)
values ('初三一班'),('初三二班'),('初三三班');
/*学生表:这边假设学生id和姓名都具有唯一性*/
DROP TABLE IF EXISTS `students`;
CREATE TABLE `students` (
`studentid` int primary key NOT NULL AUTO_INCREMENT comment '学生id',
`studentname` varchar(20) DEFAULT NULL comment '学生姓名',
`score` DECIMAL(10,2) DEFAULT NULL comment '毕业成绩',
`classid` int(4) DEFAULT NULL comment '所属班级id,来源于classes表的classid'
) ENGINE=InnoDB comment '学生表';
insert into `students`(`studentname`,`score`,`classid`) values
('brand',97.5,1),('helen',96.5,1),('lyn',96,1),('sol',97,1),('weng',100,1),('diny',92.7,1),
('b1',81,2),('b2',82,2),('b3',83,2),('b4',84,2),('b5',85,2),('b6',86,2),
('c1',71,3),('c2',72.5,3),('c3',73,3),('c4',74,3),('c5',75,3),('c6',76,3);
/*毕业考核分数排名表*/
DROP TABLE IF EXISTS `scores`;
CREATE TABLE `scores`(
`scoregrad` varchar(3) primary key comment '等级:S、A、B、C、D',
`downset` int comment '分数评级下限',
`upset` int comment '分数评级上限'
) comment '毕业考核分数排名表';
INSERT INTO `scores` values ('S', 91, 100),('A', 81, 90),('B', 71, 80),('C', 61, 70),('D', 51,60);
子查询
SQL支持创建子查询( subquery) ,就是嵌套在其他查询中的查询 ,也就是说在select语句中会出现其他的select语句,我们称为子查询或内查询。而外部的select语句,称主查询或外查询。
子查询分类
按照查询的返回结果
1、单行单列(标量子查询):返回的是一个具体列的内容,可以理解为一个单值数据;
2、单行多列(行子查询):返回一行数据中多个列的内容;
3、多行单列(列子查询):返回多行记录之中同一列的内容,相当于给出了一个操作范围;
4、多行多列(表子查询):查询返回的结果是一张临时表;
按子查询位置区分
select后的子查询:仅仅支持标量子查询,即只能返回一个单值数据。
from型子查询:把内层的查询结果当成临时表,供外层sql再次查询,所以支持的是表子查询。
where或having型子查询:指把内部查询的结果作为外层查询的比较条件,支持标量子查询(单列单行)、列子查询(单列多行)、行子查询(多列多行)。
一般会和下面这几种方式配合使用:
1)、in子查询:内层查询语句仅返回一个数据列,这个数据列的值将供外层查询语句进行比较。
2)、any子查询:只要满足内层子查询中的任意一个比较条件,就返回一个结果作为外层查询条件。
3)、all子查询:内层子查询返回的结果需同时满足所有内层查询条件。
4)、比较运算符子查询:子查询中可以使用的比较运算符如 >、>=、<=、<、=、 <>
exists子查询:把外层的查询结果(支持多行多列),拿到内层,看内层是否成立,简单来说后面的返回true,外层(也就是前面的语句)才会执行,否则不执行。
下面我们一个个来测试。
select后子查询
位于select后面,仅仅支持标量子查询,即只能返回一个单值数据。比如上面的学生班级表,我们查询每个班级的学生数量,可以这么写:
mysql> select a.classid as 班级编号,a.classname as 班级名称,
(select count(*) from students b where b.classid = a.classid) as 学生数量
from classes a;
+----------+----------+----------+
| 班级编号 | 班级名称 | 学生数量 |
+----------+----------+----------+
| 1 | 初三一班 | 6 |
| 2 | 初三二班 | 6 |
| 3 | 初三三班 | 6 |
+----------+----------+----------+
3 rows in set
查询学生brand 所属的班级,可以这么写:
mysql> select
(select classname from classes a,students b where a.classid = b.classid and b.studentname='brand')
as 班级;
+----------+
| 班级 |
+----------+
| 初三一班 |
+----------+
1 row in set
from后子查询
把内层的查询结果当成临时表,提供外层sql再次查询,支持的是表子查BL
BLHH
HBL
BKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJL[OB]Bb%[{.#"yd#9kiB]\HHBH\H\B^\ X
Y[H\HK\YH[H
X\[\Y\\\H\Y NKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJY[YY[[YHH\YBKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJH[MHHB[[MHHB[MHB
MHB
HLHB
[HLHB
HHBBHBL
BLHH
HBL
BKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJL[OB]Bb%[;d#9.[B]\HHBH\H\B^\ X
Y[H\HK\Y [
X\[\Y\\\H\Y NKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJY[YY[[YHH\YBKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJL
BM
HBMH
BM
BM
BN
BKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJ[OB]B
(c9kd9#BBic 9l#+ 9ioyd#9kiB]\HHBH\H\B^\ X
Y[H\H
KY[YKJH[
XX^
Y[Y
KZ[JHY[KKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJY[YY[[YHH\YBKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJNH[H
LHBKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJH[OB]B^\BσB.gfal#9l,y+%l`;+&(c9i&b%#9,9ayl`ayl`+$9ceyiz+#gh/YK9i%l`.g+h+"ycy/&i#9d)b&y.#yi Bx^\;y%;y..Y{9..[^\99iyb)9ykd99:f+y+"y`/8B^\#9. :"+9c*[iy#9`9.\9l$xB9bczgh`蹥yo##;ab9i.#9d#.yk..9;aykd999iz/ f.kd9+yc!yd*.+yb,9ke#9`9.gl B/蹢`9"ykid#yB]\HHBH\H\B^\ X\[YH\\H\H^\XHY[\H\YHK\Y
NBKKKKKKKKKJ\[YHBKKKKKKKKKJ9b'y."y. 9B9b'y."y.9B9b'y."y."yBKKKKKKKKKJ[OB]B/o[9iy"99 {B]\HHBH\H\B^\ X\[YH\\H\HK\Y[X\YY[BKKKKKKKKKJ\[YHBKKKKKKKKKJ9b'y."y. 9B9b'y."y.9B9b'y."y."yBKKKKKKKKKJ[OB]Bd"9BBi&l9!yd* 9.*%i&.*(j9.+z/繥l9kceyhTP+ ^T9.g9i&.*"9i&hTP+"{nml!9/g9..cey.*B:f /"9&n.9..nm[[9%i#yd"9"\]Y\{Bcez(j9i&(z/BσBl!.#yd#9蹧hy.99d"9g*9. :-mB]\HHBH\H\BX[YLK[YL[YH\H][CB[[BX[YLK[YL[YH\H][OB]Bi&(j:/#9BσBl!d#9l:a9ke"B]\HHBH\H\BXW[YLKW[YL[YLH\H][B[[BX[YLK[YL[YL\H][OB]B/y.#z-f:/#9d#gh"y.$9"+,:/*B.BBc"y:/n:++ykd99/cy.)9.*zghiyki.hB#*[[xYx[9B+++;ke+y"[[9`/9.%z-m#9nnj9e#y..% !y9`/8B."l,y+T9kd99b!:+yk{&alT9:-a9z+l/c.amkl O |