MySQL 子查询和分组查询

论坛 期权论坛 脚本     
niminba   2021-5-23 04:20   2316   0

概述

子查询是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再次查询,支持的是表子查  B L  B LHH H B L  BKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJL[ OB ]Bb%[{.#"yd#9ki B]\HHBH\H\B^\ X Y[H\HK\YH[H X\[\Y\\\H\Y NKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJY[YY[HH\YBKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJ H[MH HB [[MH HB [M HB M HB H L  HB [HL HB H H B  BH  B L  B LHH H B L  BKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJL[ OB ]Bb%[;d#9.[ B]\HHBH\H\B^\ X Y[H\HK\Y [ X\[\Y\\\H\Y NKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJY[YY[HH\YBKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJ L  B M H B MH  B M  B M  B N  BKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJ[ OB ]B (c9kd9#B Bic 9l#+ 9ioyd#9ki B]\HHBH\H\B^\ X Y[H\H KY[Y KJH[ XX^ Y[Y KZ[JHY[KKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJY[YY[HH\YBKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJ NH[H LH BKKKKKKKKKJKKKKKKKKKKKJKKKKKJKKKKKKKJH[ 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`/8 B^\#9. :"+9c*[iy#9`9.\9l$x B9bczgh`蹥yo##;ab9i.#9d#.yk..9;aykd999iz/ f.kd9+yc!yd*.+yb,9ke#9`9.gl B/蹢`9"ykid#y B]\HHBH\H\B^\ X\[YH\\H\H^\X HY[\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 ]B d"9B Bi&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\{ B cez(j9i&(z/B σBl!.#yd#9蹧hy.99d"9g*9. :-mB]\HHBH\H\BX[YLK[YLH\H][CB[[BX[YLK[YLH\H][ OB ]B i&(j:/#9B σBl!d#9l:a9ke" B]\HHBH\H\BX W[YLK W[YLLH\H][B[[BX [YLK[YLL\H][ OB ]B/y.#z-f:/#9d#gh"y.$9"+,:/* B .B Bc"y:/n:++ykd99/cy.)9.*zghiyki.h B#*[[xYx[9B+++;ke+y"[[9`/9.%z-m#9nnj9e#y..% !y9`/8 B."l,y+T9kd99b!:+yk{&alT9:-a9z+l/c.amkl O

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP