# SQL HAVING 子句

SQL中增加HAVING子句原因是: WHERE关键字无法与聚合函数一起使用

HAVING子句可以让我们筛选分组后的各组数据。

  • having关键字对group by分组后的数据进行过滤
  • having支持where的所有操作符和语法

# where 和 having 的一些差异性

where having
不可以使用聚合函数 可以使用聚合函数
数据 group by 过滤 数据 group by 过滤
查询条件中不可以使用字段别名 查询条件中可以使用字段别名
用于过滤数据行 用于过滤分组后的结果集
根据数据表的字段直接过滤 根据已查询出的字段进行过滤

# SQL 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
1
2
3
4
5

# 实战: 超过5名学生的课

有一个courses表 ,有: student (学生) 和 class (课程)。

请列出所有超过或等于5名学生的课。

例如,表:

+---------+------------+
| student | class      |
+---------+------------+
| A       | Math       |
| B       | English    |
| C       | Math       |
| D       | Biology    |
| E       | Math       |
| F       | Computer   |
| G       | Math       |
| H       | Math       |
| I       | Math       |
+---------+------------+
1
2
3
4
5
6
7
8
9
10
11
12
13

应该输出:

+---------+
| class   |
+---------+
| Math    |
+---------+
1
2
3
4
5

提示:学生在每个课中不应被重复计算。

  • 来源:力扣(LeetCode)
  • 链接:https://leetcode-cn.com/problems/classes-more-than-5-students
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

# 题解

方法一:使用 GROUP BY 子句和子查询

思路: 先统计每门课程的学生数量,再从中选择超过 5 名学生的课程。

算法: 使用 GROUP BYCOUNT 获得每门课程的学生数量。

SELECT
    class, COUNT(DISTINCT student)
FROM
    courses
GROUP BY class
1
2
3
4
5

注:使用 DISTINCT 防止在同一门课中学生被重复计算。

| class    | COUNT(student) |
|----------|----------------|
| Biology  | 1              |
| Computer | 1              |
| English  | 1              |
| Math     | 6              |
1
2
3
4
5
6

使用上面查询结果的临时表进行子查询,筛选学生数量超过5的课程。

SELECT
    class
FROM
    (SELECT
        class, COUNT(DISTINCT student) AS num
    FROM
        courses
    GROUP BY class) AS temp_table
WHERE
    num >= 5
1
2
3
4
5
6
7
8
9
10

注:COUNT(student) 不能直接在 WHERE 子句中使用,这里将其重命名为 num

方法二:使用 GROUP BYHAVING 条件【通过】

算法: 在 GROUP BY 子句后使用 HAVING 条件是实现子查询的一种更加简单直接的方法。

SELECT
    class
FROM
    courses
GROUP BY class
HAVING COUNT(DISTINCT student) >= 5
1
2
3
4
5
6

参考文档

Last Updated: 3 years ago