SQL分组查询/子查询
GROUP BY 子句
我们在日常生活中,常常会将东西分类摆放使其能看起来更井井有条,也在找寻时能更加方便。对于数据,在查询过程中,我们同样也会需要对同类的数据进行分类。
GROUP BY 函数就是 SQL 中用来实现分组的函数,其用于结合聚合函数,能根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表。
语法:
SELECT `column_name`, aggregate_function(`column_name`)
FROM `table_name`
WHERE `column_name` operator value
GROUP BY `column_name`;
👇 接下来,我们将通过一个单表实例和一个多表实例帮助你加深对 GROUP BY 子句 的理解。
GROUP BY 单表实例
可以看到我们教师表中的教师来自不同的国家,现需要统计不同国家教师的人数,并将结果按照不同国籍教师人数从小到大排列,请编写相应的 SQL 语句实现。
使用 SQL 中子查询的方式如下:
SELECT `country`, COUNT(`country`) AS `teacher_count`
FROM `teachers`
GROUP BY `country`
ORDER BY `teacher_count`, `country`;
执行输出结果:
mysql> SELECT `country`, COUNT(`country`) AS `teacher_count`
-> FROM `teachers`
-> GROUP BY `country`
-> ORDER BY `teacher_count`, `country`;
+---------+---------------+
| country | teacher_count |
+---------+---------------+
| JP | 1 |
| UK | 1 |
| USA | 1 |
| CN | 2 |
+---------+---------------+
4 rows in set (0.04 sec)
GROUP BY 多表实例
课程表的每节课程都有对应的一个教师负责授课,而每一个教师对应多门课程,现需要统计每个教师教授课程的学生总数,请编写相应的 SQL 语句实现。
使用 SQL 中子查询的方式如下:
SELECT T.name AS `teacher_name`, IFNULL(SUM(C.student_count), 0) AS `student_count`
FROM `courses` C
RIGHT JOIN `teachers` T ON C.teacher_id = T.id
GROUP BY T.id;
执行输出结果:
mysql> SELECT T.name AS `teacher_name`, IFNULL(SUM(C.student_count), 0) AS `student_count`
-> FROM `courses` C
-> RIGHT JOIN `teachers` T ON C.teacher_id = T.id
-> GROUP BY T.id;
+------------------+---------------+
| teacher_name | student_count |
+------------------+---------------+
| Southern Emperor | 1520 |
| Western Venom | 4570 |
| Eastern Heretic | 3200 |
| Northern Beggar | 0 |
| Linghu Chong | 0 |
+------------------+---------------+
5 rows in set (0.02 sec)
查询教师表 teachers,统计不同年龄教师的人数,并将结果按照年龄从大到小排列,返回列名显示为 age_count
teachers
age_count
查询教师表 teachers 和课程表 courses,统计每个老师教授课程的数量,并将结果按课程数量降序排列,课程数量相同时按教师姓名升序排列,返回老师姓名和课程数量,分别命名为 teacher_name 和 course_count
teachers
courses
teacher_name
course_count
HAVING 子句
我们在使用 WHERE 条件子句时会发现其不能与聚合函数联合使用,为解决这一点,SQL 中提供了 HAVING 子句。在使用时, HAVING 子句经常与 GROUP BY 联合使用,HAVING 子句就是对分组统计函数进行过滤的子句。
HAVING 子句对于 GROUP BY 子句设置条件的方式其实与 WHERE 子句与 SELECT 的方式类似,语法也相近,但 WHERE 子句搜索条件是在分组操作之前,而 HAVING 则是在之后。
光通过以上的描述可能体会不够,让我们看一下 HAVING 的实际应用吧!
语法:
SELECT `column_name`, aggregate_function(`column_name`)
FROM `table_name`
WHERE `column_name` operator value
GROUP BY `column_name`
HAVING aggregate_function(`column_name`) operator value;
👇 我们可以通过下面的实例来感受一下 HAVING 子句 的用法。
现需要结合教师表与课程表,统计不同教师所开课程的学生总数,对于没有任课的老师,学生总数计为 0 ,最后查询学生总数少于 3000 的教师姓名及学生总数 (别名为 student_count
),结果按照学生总数升序排列,如果学生总数相同,则按照教师姓名升序排列。
使用 SQL 中 HAVING 子句查询的方式如下:
SELECT `T`.`name` AS `name`, IFNULL(SUM(`C`.`student_count`),0) AS `student_count`
FROM `courses` `C` RIGHT JOIN `teachers` `T`
ON `C`.`teacher_id` = `T`.`id`
GROUP BY `T`.`id`
HAVING `student_count` < 3000
ORDER BY `student_count`, `name`;
执行输出结果:
mysql> SELECT `T`.`name`, IFNULL(SUM(`C`.`student_count`),0) AS `student_count`
-> FROM `courses` `C`
-> RIGHT JOIN `teachers` `T` ON `C`.`teacher_id` = `T`.`id`
-> GROUP BY `T`.`id`
-> HAVING `student_count` < 3000
-> ORDER BY `student_count`, `name`;
+------------------+---------------+
| name | student_count |
+------------------+---------------+
| Linghu Chong | 0 |
| Northern Beggar | 0 |
| Southern Emperor | 1520 |
+------------------+---------------+
3 rows in set (0.02 sec)
从 teachers 表中,筛选出同一国家的教师平均年龄大于所有教师平均年龄的国家,并获取这些国家的所有教师信息
teachers
1. SELECT 语句中的子查询
SELECT 语句中的子查询
我们之前学的都是在单个表单中进行查询,那么,当查询中需要联合多个表时,该如何实现呢?
上一节我们学到的解决方式是使用连接查询,这一节我们将介绍第二种方法:子查询。
首先,什么是子查询呢?
当一个查询是另一个查询的条件时,称之为子查询。
即在查询语句中的 WHERE 条件子句中,又嵌套了另一个查询语句。
因此,子查询本质上就是一个完整的 SELECT 语句,它可以使一个 SELECT、INSERT INTO 语句、DELETE 语句或 UPDATE 语句嵌套在另一子查询中。子查询的输出可以包括一个单独的值(单行子查询)、几行值(多行子查询)、或者多列数据(多列子查询)。
这里,我们先了解一下基础的 SELECT 语句嵌套子查询。
语法:
SELECT `column_name(s)`
FROM `table_name`
WHERE `column_name` OPERATOR (
SELECT `column_name(s)`
FROM `table_name`
);
以及,SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。
👇 我们可以通过下面的实例来感受一下 SELECT 语句中的子查询 的用法。
小明想了解 Western Venom 老师所教的所有课程的所有信息,现请你来帮助他查询相关信息。
首先需要在 teachers
表中查询姓名为 Western Venom 的老师,再根据其教师 id 在 courses
表中选择对应教师 id 的所有课程信息。
因此,这里我们首先需要通过嵌套子查询到的信息为教师 id,父查询则为全部课程信息。
使用 SQL 中子查询的方式如下:
SELECT *
FROM `courses`
WHERE `teacher_id` = (
SELECT `id`
FROM `teachers`
WHERE `name` = 'Western Venom'
);
执行输出结果:
mysql> SELECT *
-> FROM `courses`
-> WHERE `teacher_id` = (
-> SELECT `id`
-> FROM `teachers`
-> WHERE `name` = 'Western Venom'
-> );
+----+-------------------------+----------------+-------------+------------+
| id | name | student_count | created_at | teacher_id |
+----+-------------------------+----------------+-------------+------------+
| 2 | System Design | 135 | 2020-07-18 | 3 |
| 3 | Django | 78 | 2020-02-29 | 3 |
| 6 | Artificial Intelligence | 166 | 2018-05-13 | 3 |
| 7 | Java P6+ | 78 | 2019-01-19 | 3 |
+----+-------------------------+----------------+-------------+------------+
4 rows in set (0.01 sec)
courses
teachers
INSERT 语句中的子查询
上一节我们学习了 SELECT 语句中的子查询,那么对于在同为简单语句之一的 INSERT 语句中,能否使用子查询呢?
答案是可以的。其实,子查询不仅仅可以嵌套在 SELECT 语句中用于构造父查询的条件,也可以嵌套在 INSERT 语句中用于插入数据。
对于 INSERT 语句中的子查询来说,首先是使用子查询的 SELECT 语句找到需要插入的数据,之后将返回的数据插入到另一个表中。在子查询中所选择的数据可以用任何字符、日期或数字函数修改。
那么,接下来就让我们一起来学习一下基础的 INSERT 语句中的子查询吧!
语法:
INSERT INTO `table_name`
SELECT `colnum_name(s)`
FROM `table_name`
[ WHERE VALUE OPERATOR ]
注意:INSERT 语句中的子查询其实是将一个表中查询到的数据“复制”到另一个表中,由于主键具有唯一性,如果需要仅在单张表中使用 INSERT 子查询,只能在无主键的单张表中进行操作,否则,需要有两张表(如只一张表,则需新建一张表)。
👇 我们可以通过下面的实例来感受一下 INSERT 语句中的子查询 的用法。
小明在整理数据时发现教师表未备份,为了及时完善数据的备份,现在需要将教师表 teachers
中的全部信息复制到相同表结构的备份表 teachers_bkp
中,请使用相关 SQL 语句完成教师表的备份。
首先我们需要查询教师表 teachers
中的所有信息,再将查询到的数据插入到备份表 teachers_bkp
中。即,查询教师表 teachers
中的所有信息为插入备份表 teachers_bkp
中的条件。
因此,这里我们首先需要通过嵌套子查询到的信息为教师表 teachers
中的所有信息,而整个语句是为了插入数据。
使用 SQL 中子查询的方式如下:
INSERT INTO `teachers_bkp`
SELECT *
FROM `teachers`;
执行输出结果:
mysql> INSERT INTO `teachers_bkp`
-> SELECT *
-> FROM `teachers`;
Query OK, 3 rows affected (0.05 sec)
Records: 3 Duplicates: 0 Warnings: 0
在插入成功后,我们再对 teachers_bkp
表进行查询,查看插入结果:
mysql> SELECT * FROM `teachers_bkp`;
+----+------------------+---------------------------+-----+---------+
| id | name | email | age | country |
+----+------------------+---------------------------+-----+---------+
| 1 | Eastern Heretic | eastern.heretic@gmail.com | 20 | CN |
| 2 | Northern Beggar | northern.beggar@qq.com | 21 | CN |
| 3 | Western Venom | western.venom@163.com | 28 | USA |
| 4 | Southern Emperor | southern.emperor@qq.com | 21 | CN |
| 5 | Linghu Chong | NULL | 18 | CN |
+----+------------------+---------------------------+-----+---------+
5 rows in set (0.05 sec)
将教师表 teachers 中年龄大于 20(不包括 20) 的教师的数据复制到与它结构相同的空表 teachers_bkp 表中
UPDATE 语句中的子查询
在经过对 INSERT 语句中子查询的了解之后,同样,这一节我们将对在 UPDATE 语句中使用子查询进行学习。
对于 UPDATE 语句,首先通过 SELECT 语句查询需要更新的信息,再使用 UPDATE 语句对信息进行更新。当通过 UPDATE 语句使用子查询时,能够实现表中单个列或多个列的数据更新。
那么,接下来就让我们一起来学习一下基础的 UPDATE 语句中的子查询吧!
语法:
UPDATE `table_name`
SET `column_name` = `new_value`
WHERE `column_name` OPERATOR
(SELECT `column_name`
FROM `table_name`
[WHERE] )
注意:在 UPDATE 语句的子查询中,子查询 SELECT 语句所用的表和 UPDATE 语句所要更改的表不能是同一张表!
👇 我们可以通过下面的实例来感受一下 UPDATE 语句中的子查询 的用法。
学校教务处排课时发现教师 Western Venom 创建的课程有误,现紧急需要将该教师创建的课程名称修改为 Java,请你使用相关的 SQL 语句完成。
首先我们需要在教师表 teachers
中查询到教师 Western Venom ,再根据其教师 id 在课程表 course
中查询该教师 id 所创建的课程名称 name
,最后将查询到的课程更改为 Java。
因此,这里我们首先需要通过嵌套子查询到的信息为教师 id,而整个语句是为了更新数据。
使用 SQL 中子查询的方式如下:
UPDATE `courses`
SET `name` = 'Java'
WHERE `teacher_id` = (
SELECT `id`
FROM `teachers`
WHERE `name` = 'Western Venom'
);
执行输出结果:
mysql> UPDATE `courses`
-> SET `name` = 'Java'
-> WHERE `teacher_id` = (
-> SELECT `id`
-> FROM `teachers`
-> WHERE `name` = 'Western Venom'
-> );
Query OK, 4 rows affected (0.05 sec)
Records: 4 Duplicates: 0 Warnings: 0
DELETE 语句中的子查询
通过学习 SELECT 、INSERT 、UPDATE 语句中的子查询,相信大家对于简单语句与子查询的结合使用也有了一定的了解。可以发现,根据子查询由里及外的求解方式,子查询就如同“定位”,帮父查询找到需要的数据,再对这些数据进行进一步的增删改查。
那么,同样的,DELETE 语句中的子查询也近乎是同样的模式。
对于 DELETE 语句,首先通过 SELECT 语句查询需要删除的数据,再使用 DELETE 语句对数据进行删除。当通过 DELETE 语句使用子查询时,可以完成复杂的数据删除控制。
接下来就让我们一起来学习一下 DELETE 语句中的子查询吧!
语法:
DELETE FROM `table_name`
WHERE `column_name` OPERATOR
(SELECT `column_name`
FROM `table_name`
[WHERE] )
注意:在 DELETE 语句的子查询中,子查询 SELECT 语句所用的表和 DELETE 语句所要更改的表不能是同一张表!
👇 我们可以通过下面的实例来感受一下 DELETE 语句中的子查询 的用法。
现需要删除课程表中所有教师年龄小于 21 岁(不包括 21 岁)的课程,请你使用相关的 SQL 语句实现。
首先我们需要在教师表 teachers
中查询到教师年龄小于 21 岁的老师的教师 id ,再根据其教师 id 在课程表 course
中查询该教师 id 所创建的课程并将课程删除。
因此,这里我们首先需要通过嵌套子查询到的信息为符合条件的教师 id,而整个语句是为了删除数据。
使用 SQL 中子查询的方式如下:
DELETE FROM `courses`
WHERE `teacher_id` IN (
SELECT `id`
FROM `teachers`
WHERE `age` < 21
);
执行输出结果:
mysql> DELETE FROM `courses`
-> WHERE `teacher_id` IN (
-> SELECT `id`
-> FROM `teachers`
-> WHERE `age` < 21
-> );
Query OK, 6 rows affected (0.05 sec)
Records: 6 Duplicates: 0 Warnings: 0
在删除成功后,我们再对 courses
表进行查询,查看删除结果:
mysql> SELECT * FROM courses;
+----+-------------------------+---------------+------------+------------+
| id | name | student_count | created_at | teacher_id |
+----+-------------------------+---------------+------------+------------+
| 1 | Advanced Algorithms | 880 | 2020-06-01 | 4 |
| 2 | System Design | 1350 | 2020-07-18 | 3 |
| 3 | Django | 780 | 2020-02-29 | 3 |
| 4 | Web | 340 | 2020-04-22 | 4 |
| 6 | Artificial Intelligence | 1660 | 2018-05-13 | 3 |
| 7 | Java P6+ | 780 | 2019-01-19 | 3 |
| 10 | Object Oriented Design | 300 | 2020-08-08 | 4 |
+----+-------------------------+---------------+------------+------------+
7 rows in set (0.00 sec)
1. 内联视图子查询
内联视图子查询
我们在 Level 1 中有学习到 SELECT 语句的语法,为:SELECT column_name FROM table_name
,结合我们前面学习的子查询的方法,我们是将子查询插入到列名 column_name
的位置,将子查询的结果作为列名,而本节我们将介绍的内联视图子查询,是将子查询插入到表名 table_name
的位置。
内联视图子查询实际上就是将查询的结果集作为一个查询表,继续进行查询操作。
👇 我们可以通过下面的实例来感受一下 内联视图子查询 的用法。
现需要查询国籍为美国(USA),且年龄最大的教师,请使用内联视图子查询实现。
本题将从教师表中查询到的美国教师作为内联表,再使用 WHERE 子句进行查询操作。
使用 SQL 中内联视图子查询的方式如下:
SELECT *
FROM (
SELECT *
FROM `teachers`
WHERE `country` = 'USA'
) `T`
WHERE `age` = (
SELECT MAX(`age`)
FROM `teachers`
);
其实本题还可以将最大年龄作为内联表哦!
执行输出结果:
mysql> SELECT *
-> FROM (
-> SELECT *
-> FROM `teachers`
-> WHERE `country` = 'USA'
-> ) `T`
-> WHERE `age` = (
-> SELECT MAX(`age`)
-> FROM `teachers`
-> );
+----+---------------+-----------------------+-----+---------+
| id | name | email | age | country |
+----+---------------+-----------------------+-----+---------+
| 3 | Western Venom | western.venom@163.com | 28 | USA |
+----+---------------+-----------------------+-----+---------+
1 row in set (0.03 sec)
IN 操作符的多行子查询
大家还记得在 Level 2 的特殊条件一章中学到的 IN 操作符吗?
没错!当时我们通过使用 IN 操作符方便地将多个条件连接了起来,并对单表进行了查询。而本节我们将结合 IN 操作符对多行子查询进行学习。
使用 IN 操作符进行子查询,其实是将子查询返回的集合和外层查询得到的集合进行交集运算,这个结果可以是零个值,也可以是多个值。由此,最后可以查询出与列表中任意一个值匹配的行。
语法:
SELECT `column_name`
FROM `table_name`
WHERE `column_name` IN(
SELECT `column_name`
FROM `table_name`
WHERE `column_name` = VALUE
);
👇 我们可以通过下面的实例来感受一下 IN 操作符多行子查询 的用法。
现需要查询国籍为美国(USA)的教师所开的所有课程,请使用 IN 操作符进行多行子查询。
为了得到满足条件的课程名称,我们首先需要在教师表 teachers
中进行查询,查询数据为国籍 country
为美国(USA)的教师所对应的教师 id,再根据这个 id ,在课程表courses
中进行查询,最终得到所有的课程名称 name
。
这里,我们首先需要通过嵌套子查询到的信息为国籍为美国的全部教师的教师 id,父查询为查询满足条件的课程名称。
使用 SQL 中子查询的方式如下:
SELECT `name`
FROM `courses`
WHERE `teacher_id` IN (
SELECT `id`
FROM `teachers`
WHERE `country` = 'USA'
);
执行输出结果:
mysql> SELECT `name`
-> FROM `courses`
-> WHERE `teacher_id` IN (
-> SELECT `id`
-> FROM `teachers`
-> WHERE `country` = 'USA'
-> );
+-------------------------+
| name |
+-------------------------+
| System Design |
| Django |
| Artificial Intelligence |
| Java P6+ |
+-------------------------+
4 rows in set (0.12 sec)
3. ANY 操作符的多行子查询
ANY 操作符的多行子查询
在学习了 IN 操作符实现多行子查询后,我们不禁会产生思考:除了使用 IN 操作符,还有什么方法能进行多行子查询呢?
而这一节我们就能够学习到另一种实现多行子查询的方式:使用 ANY 操作符进行多行子查询。
但在学习之前,我们需要了解一下操作符 ANY 。
操作符 ANY 属于逻辑运算符的一种,与 IN 运算符不同,ANY 必须和其它的比较运算符共同使用,其表示查询结果中的任意一个。
在子查询中使用 ANY ,表示与子查询返回的任何值比较为真,则返回真。
语法:
SELECT `column_name(s)`
FROM `table_name`
WHERE `column_name` OPERATOR
ANY(SELECT column_name
FROM table_name)
现需要查询学生上课人数超过 “Eastern Heretic” 的任意一门课的学生人数的课程信息,请使用 ANY 操作符实现多行子查询。
第一层的父查询为在课程表 courses
中查询满足条件的全部课程信息,这个条件由子查询来完成,即为,查询学生上课人数超过 ”Eastern Heretic“ 的任意一门课的学生人数。这一部分的子查询中需要结合 ANY 操作符实现。之后,再将子查询进行拆分,形成第二层的嵌套子查询。
第二层的父查询为在课程表 courses
中根据教师 id 查询学生上课人数, 其子查询为在教师表 teachers
中查找教师名 name
为 “Eastern Heretic” 的教师 id。
由于我们最终得到的课程信息中肯定不包含 “Eastern Heretic” 的课程,所以我们要在 WHERE 条件中再设置一项:不为 “Eastern Heretic” 所开的课程 。
结合以上,使用 SQL 中子查询的方式如下:
SELECT *
FROM `courses`
WHERE `student_count` > ANY (
SELECT `student_count`
FROM `courses`
WHERE `teacher_id` = (
SELECT `id`
FROM `teachers`
WHERE `name` = 'Eastern Heretic'
)
)
AND `teacher_id` <> (
SELECT `id`
FROM `teachers`
WHERE `name` = 'Eastern Heretic'
);
ALL 操作符的多行子查询
除了 IN 、 ANY 外,ALL 也经常在多行子查询中被使用到。
首先,我需要了解一下 ALL 操作符。
与 ANY 一样,操作符 ALL 也属于逻辑运算符的一种,且都须与其它的比较运算符共同使用,其表示查询结果中的所有。
在子查询中使用 ALL ,表示与子查询返回的所有值比较为真,则返回真。
语法:
SELECT `column_name(s)`
FROM `table_name`
WHERE `column_name` OPERATOR
ALL(SELECT column_name
FROM table_name)
现需要查询学生人数超过 ”Western Venom“ 所有课程学生人数的课程信息,请使用 ALL 操作符实现多行子查询。
第一层的父查询为在课程表 courses
中查询满足条件的全部课程信息,这个条件由子查询来完成,即为,查询学生人数超过 ”Western Venom“ 所有课程学生人数。这一部分的子查询中需要结合 ALL 操作符实现。之后,再将子查询进行拆分,形成第二层的嵌套子查询。
第二层的父查询为在课程表 courses
中根据教师 id 查询学生上课人数, 其子查询为在教师表 teachers
中查找教师名 name
为 ”Western Venom“ 的教师 id。
结合以上,使用 SQL 中子查询的方式如下:
SELECT *
FROM `courses`
WHERE `student_count` > ALL (
SELECT `student_count`
FROM `courses`
WHERE `teacher_id` = (
SELECT `id`
FROM `teachers`
WHERE `name` = 'Western Venom'
)
);
多列子查询
上一章我们了解了多行子查询,这一章我们将对多列子查询进行学习。
对于多列子查询:
当是单行多列的子查询时,主查询语句的条件语句中引用子查询结果时可用单行比较符号(=,>,<,>=,<=, <> 等)来进行比较;
当是多行多列子查询时,主查询语句的条件语句中引用子查询结果时必须用多行比较符号(IN,ANY,ALL 等)来进行比较。
👇 我们可以通过下面的实例来感受一下 多列子查询 的用法。
现需要找到每个国家年龄最大的教师,请编写 SQL 语句实现多列子查询
使用 SQL 中子查询的方式如下:
SELECT `name`, `age`, `country`
FROM `teachers`
WHERE (`country`, `age`) IN (
SELECT `country`, MAX(`age`)
FROM `teachers`
GROUP BY `country`
);
执行输出结果:
mysql> SELECT `name`, `age`, `country`
-> FROM `teachers`
-> WHERE (`country`, `age`) IN (
-> SELECT `country`, MAX(`age`)
-> FROM `teachers`
-> GROUP BY `country`
-> );
+------------------+-----+---------+
| name | age | country |
+------------------+-----+---------+
| Eastern Heretic | 20 | UK |
| Northern Beggar | 21 | CN |
| Western Venom | 28 | USA |
| Southern Emperor | 21 | JP |
+------------------+-----+---------+
4 rows in set (0.06 sec)
HAVING 子句中的子查询
还记得在本阶段在学习子查询之前我们了解的 HAVING 子句吗?尽管通常在 WHERE 子句中使用子查询作为搜索条件,但有时也可以在查询的 HAVING 子句中使用子查询,本节我们将学习 HAVING 子句与子查询的结合运用。
当子查询出现在 HAVING 子句中时,像 HAVING 子句中的任何表达式一样,表示要进行分组过滤,它被用作行组选择的一部分,一般返回单行单列的数据。
👇 我们可以通过下面的实例来感受一下 HAVING 子查询 的用法。
现需要计算每位教师所开课程的平均学生人数与全部课程的平均学生人数,比较其大小,最后返回超过全部课程平均学生人数的教师姓名,请编写相应的 SQL 语句实现。
本题需要使用 HAVING 语句根据教师 id 进行分组,实现“计算每位教师所开课程的平均人数”,并使用子查询实现其与“全部课程的平均人数”的比较。
使用 SQL 中 HAVING 子查询的方式如下:
SELECT `name`
FROM `teachers`
WHERE `id` IN (
SELECT `teacher_id`
FROM `courses`
GROUP BY `teacher_id`
HAVING AVG(`student_count`) > (
SELECT AVG(`student_count`)
FROM `courses`
)
);
执行输出结果:
mysql> SELECT `name`
-> FROM `teachers`
-> WHERE `id` IN (
-> SELECT `teacher_id`
-> FROM `courses`
-> GROUP BY `teacher_id`
-> HAVING AVG(`student_count`) > (
-> SELECT AVG(`student_count`)
-> FROM `courses`
-> )
-> );
+-----------------+
| name |
+-----------------+
| Eastern Heretic |
| Western Venom |
+-----------------+
2 rows in set (0.09 sec)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性