MySQL数据库 - 分组选择数据

本文通过具体案例介绍如何使用SQL中的GROUP BY结合聚合函数进行数据分组,并利用HAVING子句进行分组后的筛选。此外,还展示了如何对查询结果进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第1关:GROUP BY 与 聚合函数

任务描述

本关任务:使用GROUP BY关键字结合聚合函数将数据进行分组。

相关知识

在之前的实训中我们简单的提到过GROUP BY关键字,本实训让我们进一步了解GROUP BY与聚合函数的使用。

为了完成本关任务,你需要掌握: 1.GROUP BY与聚合函数的结合使用; 2.GROUP BYSELECT指定的字段限制。

GROUP BY与聚合函数的使用

基本格式:

select [聚合函数] 字段名 from 表名 [where 查询条件] [group by 字段名]

先提供表Info结构如下:

categorycountdigest
a5a2002
a2a2001
a11a2001
b10b2003
b6b2002
b3b2001
c9c2005
c9c2004
c8c2003
c7c2002
c4c2001

示例:将表中数据分类并汇总

在这里插入图片描述

GROUP BYSELECT指定的字段限制

示例:

select category,sum(count),disgest from info group by category;

执行后会提示下错误,如下图。这就是需要注意的一点,在select指定的字段要么就要包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中

在这里插入图片描述

编程要求

在右侧编辑器补充代码,对年级Id和性别进行分组,分别统计表中2、3、4年级的男生总人数和女生总人数。

student表数据结构如下:

stuIdgradeIdsex
02012
02212
03193
05085
06106
01011
02242
04134

要求输出结果显示如下:

在这里插入图片描述

测试说明

平台会对你编写的代码进行测试:

预期输出:

gradeId    sex    count(*)  
2         女      1  
2         男      2  
3         女      1  
4         女      1

开始你的任务吧,祝你成功!

USE School;

#请在此处添加实现代码
########## Begin ##########

#1.查询表中2,3,4年级中分别男女的总人数
select gradeId,sex,count(*) 
from student where gradeId IN (2,3,4) 
group by gradeId,sex;

########## End ##########

第2关:使用 HAVING 与 ORDER BY

任务描述

本关任务:按照要求编写sql查询语句。

相关知识

为了完成本关任务,你需要掌握:

1.使用having子句进行分组筛选;

2.HavingWhere的区别;

3.Group ByOrder By

使用having子句进行分组筛选

简单来说,having子句用来对分组后的数据进行筛选,即having针对查询结果中的列发挥筛选数据作用。因此having通常与Group by连用。

基本格式:

select [聚合函数] 字段名 from 表名 [where 查询条件] [group by 字段名] [having 字段名 筛选条件]

Info的数据信息仍如下:

categorycountdigest
a5a2002
a2a2001
a11a2001
b20b2003
b15b2002
b3b2001
c9c2005
c9c2004
c8c2003
c7c2002
c4c2001

示例:查询将表中数据分类后数量大于20的类别信息

在这里插入图片描述

select语句中,wheregroup byhaving子句和聚合函数的执行次序如下:

1.where子句从数据源中去除不符合条件的数据;

2.然后group by子句搜集数据行到各个组中;

3.接着统计函数为各个组计算统计值;

4.最后having子句去掉不符合其组搜索条件的各组数据行。

HavingWhere的区别

where子句都可以用having代替,区别在于where过滤行,having过滤分组;

  • where子句的作用是在对查询结果进行分组前,将不符合where条件的去掉,即在分组之前过滤数据,where条件中不能包含聚组函数,使用where条件过滤出特定的行;
  • having子句的作用是筛选满足条件的,即在分组之后过滤数据,条件中经常包含聚组函数,使用having条件过滤出特定的组,也可以使用多个分组标准进行分组。

having结合where示例:

在这里插入图片描述

Group ByOrder By

基本格式

select [聚合函数] 字段名 from 表名 [where 查询条件] [group by 字段名] [order by 字段名 排序方向]

示例:(以降序方式输出数据分类的汇总)

在这里插入图片描述

若分组字段和排序字段一样时,可不需要order by关键字,则只需告知排序方向,即可简写成:

在这里插入图片描述

编程要求

根据提示,在右侧编辑器补充代码:

  1. 我们要评选三好学生,条件是**至少有两门课程在90分以上(包括90分)**才能有资格,请列出符合的学生的学号(sno)及其90分以上(包括90分)科目总数;
  2. 学校评选先进学生,要求**平均成绩大于90分(包括90分)**的学生都有资格,并且语文课必须在95分以上(包括95分),请列出有资格的学生的学号(sno)及其科目的平均分。

给定数据表tb_grade格式如下:

snopnoscore
1语文95
1数学98
1英语90
2语文89
2数学91
2英语92
3语文85
3数学88
3英语96
4语文95
4数学89
4英语88
测试说明

平台会对你编写的代码进行测试:

预期输出:

sno    count(*)
1        3
2        2
sno    avg(score)
1        94.3333
4        90.6667

开始你的任务吧,祝你成功!

USE School;

#请在此处添加实现代码
########## Begin ##########

#1.查询表中至少有两门课程在90分以上的学生信息
select sno,count(*) 
from tb_grade
where score>=90 
group by sno 
having  count(pno)>=2;


#2.查询表中平均成绩大于90分且语文课在95分以上的学生信息
select sno,avg(score) from tb_grade 
where sno in(select sno from tb_grade where pno = "语文" and score >= 95)
group by sno having avg(score) >=90;



########## End ##########

### MySQL 数据库分组查询方法 在 MySQL 中,`GROUP BY` 是一种用于将数据按照指定列进行分组的强大工具。通过 `GROUP BY` 结合聚合函数(如 `COUNT()`、`SUM()`、`AVG()`、`MAX()` 和 `MIN()`),可以轻松完成复杂的统计分析。 以下是基于提供的引用内容以及标准 SQL 实践的一个具体示例: #### 示例场景 假设有一个名为 `student_scores` 的表,结构如下: | student_id | subject | score | |------------|----------|-------| | 1 | Math | 80 | | 2 | English | 90 | | 3 | Math | 75 | | 4 | Science | 85 | 目标是从该表中查询每一门课程 (`subject`) 的最高分数及其对应的学生 ID。 #### 查询语句 ```sql SELECT s.student_id, s.subject, MAX(s.score) AS max_score FROM student_scores s GROUP BY s.subject; ``` 上述查询会返回每个学科的最高分数及对应的任意学生 ID[^1]。然而,在某些情况下可能需要确保返回的是具有最高分数的具体记录而非随机选取的一条记录,则可以通过子查询的方式进一步优化。 #### 子查询方式 如果希望精确匹配到拥有最高成绩的学生信息,可采用以下形式: ```sql SELECT ss.student_id, ss.subject, ss.score FROM student_scores ss JOIN ( SELECT subject, MAX(score) as max_score FROM student_scores GROUP BY subject ) grouped ON ss.subject = grouped.subject AND ss.score = grouped.max_score; ``` 此查询首先计算各科目的最大得分 (内部嵌套部分),然后将其与原始表格连接起来以提取完整的行数据[^2]。 #### 性能调优建议 为了提高此类查询性能,可以从以下几个方面入手: - 对于频繁使用的 `GROUP BY` 字段创建索引能够显著提升效率[^3]; - 如果不需要额外排序操作,可以在最终查询附加 `ORDER BY NULL` 来避免不必要的开销; - 尽量减少参与运算的数据量并充分利用内存中的临时存储资源。 以上即为利用 MySQL 进行复杂分组筛选的一种常见模式说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值