SQL题收集
Xplorist Lv6

SQL题收集

reference-site-list

steps

分组统计

  • group by - having

  • 题目:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    mysql> select * from table_class;
    +----+--------+---------+-------+
    | id | name | subject | score |
    +----+--------+---------+-------+
    | 1 | 赵六 | 语文 | 83 |
    | 2 | 钱七 | 语文 | 87 |
    | 3 | 王五 | 英语 | 81 |
    | 4 | 张三 | 数学 | 96 |
    | 5 | 王五 | 语文 | 84 |
    | 6 | 钱七 | 数学 | 89 |
    | 7 | 张三 | 语文 | 82 |
    | 8 | 赵六 | 英语 | 98 |
    | 9 | 李四 | 语文 | 95 |
    | 10 | 钱七 | 英语 | 87 |
    | 11 | 李四 | 英语 | 92 |
    | 12 | 张三 | 英语 | 90 |
    | 13 | 李四 | 数学 | 94 |
    | 14 | 赵六 | 数学 | 87 |
    | 15 | 王五 | 数学 | 82 |
    +----+--------+---------+-------+
    数据如上:使用SQL查询所有课程都>=90分的人的姓名
    并使用两种不同的写法。

  • 答案:

    • 方法1:求补集,先求出不符合要求的人(分数小于90,只要有一门小于90就算),然后将这些人排除,剩下的就是要查的人。核心逻辑:目标集合比较复杂,条件较多,但是它的补集相对简单,就换算成全集减去目标集合的补集。

这种方法适合于在不知道group by - having的情况下去求解

1
2
3
4
5
select a.name from (
select t.name from table_class t group by t.name
) a where a.name not in (
select b.name from table_class b where b.score < 90 group by b.name
) group by a.name
  • 方法2:正向求,直接使用group by - having 查询每组里面最小的分数都大于等于90的组。核心逻辑:该分组里最小的分数都大于等于90,那么其他数都大于等于90。
    利用了having是在group by 后面做条件查询,分组里的条件,真的非常方便
1
select t.name from table_class t group by t.name having min(t.score) >= 90
 评论