avg最多用多少列 mysql_MySQL数分:汇总分析

开始之前,先考虑一个问题:如何计算各科的平均成绩并且得出平均成绩大于等于80分的课程并降序排列?

如果面试官问我们这么一道题,先不要着急,捋一下思路:

要计算每一门课程的平均成绩,然后根据得出的结果,进行大于等于80分的条件查询,对查询结果进行降序排列。

这么看来,这道题便可以解决了~

接下来,我们需要解决的问题就是,每一步骤如何去解。以下实例均以此表为例

目录汇总函数

分组

对分组结果指定条件

排序

用SQL解决业务问题分析思路

番外:练习篇

汇总函数

一开始的问题中,要求我们计算平均成绩,平均成绩用SQL怎么来计算?这便是我们这节的内容了,这里不仅仅介绍平均值,还有计数、求和、最大值、最小值的汇总函数的介绍。

先看一下本节导图:

1)count() 求某列的行数

很容易理解,count(列名)就是求某列的行数,值得注意的一点是该列不会计算空值的行数。举例:

-- 查询共有几名教师SELECT COUNT(教师姓名) FROM teacher;

-- 查询教师表共有多少行SELECT COUNT(*) FROM teacher;

可以看出,当对所有列count(*) ,结果就是行数的最大值;

如果列中有重复值,我们计数不想计算重复值,怎么办呢?我们可以使用distinct来解决:

-- 查询成绩表里共有几个学生的成绩SELECT COUNT(DISTINCT 学号) FROM score;

2)sum() 对某列数据求和

求和,就是对某一列的数值进行求和,只能对数值进行计算。举例:

-- 对所有成绩求和SELECT SUM(成绩) FROM score;

3)avg() 对某列数值求平均值

同样,平均值的计算只能对数值进行计算:

-- 对所有成绩求平均值SELECT AVG(成绩) FROM score;

4)max() 求某列数据的最大值、min() 求某列数据的最小值

-- 获取所有成绩中的最大成绩SELECT MAX(成绩),MIN(成绩) FROM score;

分组

问题中,我们提到,需要知道每科成绩的平均成绩,那么我们就需要进行分组。

SQL中,group by语句可以根据一列或者多列对结果集进行分组。举例:

-- 对每门课程进行分组,计算每门课程有几名学生SELECT 课程号,COUNT(学号) FROM score GROUP BY 课程号;

-- 计算每一科课程的平均成绩SELECT 课程号,AVG(成绩) FROM score GROUP BY 课程号;

和刚才简单的汇总函数相比,这次我们在汇总函数的基础上增加了group by语句,那SQL的执行顺序是怎么样的呢?见下图:

在上篇文章中,我们就有简单的介绍SQL语句执行顺序:先执行from从哪个表获取数据,再执行select语句;A九姑娘:MySQL数分:简单查询​zhuanlan.zhihu.com

这里我们从成绩表获取数据,使用group by语句将数据按某种规则进行分组;然后在分组的结果上进行计算count();最后select组合结果,把上一步的每一组计算结果总结到一个表中。

对分组条件指定条件

在一开始的问题里,要求“计算各科的平均成绩并且得出平均成绩大于等于80分”,以上两节我们得到了计算每天一科的平均成绩,现在对平均成绩指定条件:“大于等于80分”,我们使用having子句。

having子句与where子句都是有条件的选取数据,不同的是where不能与汇总函数一起使用。

-- 计算平均成绩大于等于80分的课程;SELECT 课程号,AVG(成绩) FROM score GROUP BY 课程号 HAVING AVG(成绩)>=80;

那是不是说,having子句的顺序也是在select结果汇总的前边呢?

是哒,很聪明~having子句是对group by 的分组结果指定条件,比如要求大于等于80分,筛选出结果后,在进行结果汇总。

对查询结果排序

还是回到刚才的问题:“计算各科的平均成绩并且得出平均成绩大于等于80分的课程并降序排列”,我们以上3节已经得出了“平均成绩大于等于80分的课程”,那接下来就是降序了。这里我们介绍一个新的语句——order by语句。

order by语句用于根据指定的列对结果进行排序;order by语句默认是按照升序进行排列的。

降序使用desc关键字,升序使用asc关键字。

我们继续解答刚才的问题:

-- 计算平均成绩大于等于80分的课程并根据成绩降序排列;SELECT 课程号,AVG(成绩) FROM score GROUP BY 课程号 HAVING AVG(成绩)>=80 ORDER BY AVG(成绩) DESC;

看上去,我们文章开头的问题就很简单的解决了~

关于order by的执行顺序,是与group by不同的,因为order by是对分组结果进行降序,所有order by语句是在select语句之后的。

我们试着对教师表根据教师姓名排序,看一下:

-- 对教师表根据教师姓名排序SELECT * FROM teacher ORDER BY 教师姓名;

我们发现,空值Null排在了最前面,所以:含有空值的列在排序时候,空值null会在开头,当数据量很大想看空值的情况,就可以用这个排序。

另外,在补充一个limit语句,从查询结果中取出指定行,比如,我们如果从刚才的查询结果中只取第一行:

-- 计算平均成绩大于等于80分的课程并根据成绩降序排,并获取第一行SELECT 课程号,AVG(成绩) FROM score GROUP BY 课程号 HAVING AVG(成绩)>=80 ORDER BY AVG(成绩) DESC LIMIT 1;

接下来我们进行一个总结。

用SQL解决业务问题分析思路

简单来说:明确问题,将问题翻译成大白话,逐步进行拆解,并写出分析思路和对应的SQL思路。

1) 明确问题,将问题翻译成大白话:

“计算各科的平均成绩并且得出平均成绩大于等于80分的课程并降序排列”翻译成大白话就是:

“计算每一门课程的平均成绩,然后根据得出的结果,进行大于等于80分的条件查询,对查询结果进行降序排列”。

2) 逐步进行拆解,并写出分析思路和对应的SQL思路:

① 对课程号进行分组,计算每一门课程的平均成绩;

② 对①的结果指定条件“>=80”;

③ 对②的结果进行降序排列;

我们可以把拆解后的思路套用到下方的公式中:

select 查询结果

from 从那张表中查找数据

where 查询条件(运算符、模糊查询)

group by 分组(每个)

having 对分组结果指定条件

order by 对查询结果排序

limit 从查询结果中取出指定行;

试一下吧:

select 查询结果[课程号,avg(成绩)]

from 从那张表中查找数据[成绩表score]

where 查询条件(运算符、模糊查询)[No]

group by 分组(每个)[课程号]

having 对分组结果指定条件[avg(成绩)>=80]

order by 对查询结果排序[avg(成绩)desc]

limit 从查询结果中取出指定行;[No]

这样子,问题是不是就迎刃而解呢?

最后,我们根据上述思路进行练习(不感兴趣的童鞋可以看其他篇了呢):

番外:练习篇

-- 查询课程号为0002的总成绩/*SELECT 查询结果:sum(成绩)FROM 从那张表获取数据: scoreWHERE 查询条件:课程号0002*/

SELECT SUM(成绩) FROM score WHERE 课程号 = '0002';

-- 查询选了课程的学生人数/*翻译大白话:对成绩表中所有课程下的学生学号计数SELECT 查询结果:count(DISTINCT学号)FROM 从那张表获取数据: score*/

SELECT COUNT(DISTINCT 学号) FROM score;

-- 查询各科成绩最高分最低分/*翻译大白话:对成绩表中所有课程分组,然后对分组结果求最大值最小值SELECT 查询结果:课程号,MAX(成绩),MIN(成绩)FROM 从那张表获取数据: scoreGROUP BY 课程号;*/

SELECT 课程号,MAX(成绩),MIN(成绩) FROM score GROUP BY 课程号;

-- 查询每门课程被选修的学生人数/*译大白话:对成绩表中所有课程分组,然后对分组结果中的学号计数SELECT 查询结果:课程号,COUNT(DISTINCT 学号))FROM 从那张表获取数据: scoreGROUP BY 课程号;*/

SELECT 课程号,COUNT(DISTINCT 学号) FROM score GROUP BY 课程号;

-- 查询男生女生人数/*译大白话:对学生表中所有性别分组,然后对分组结果中的学号计数SELECT 查询结果:性别,COUNT(DISTINCT 学号))FROM 从那张表获取数据: studentGROUP BY 性别;*/

SELECT 性别,COUNT(DISTINCT 学号) FROM student GROUP BY 性别;

-- 查询平均成绩大于60分的学生学号/*译大白话:对学生表中根据学号分组,然后对分组结果中的学号计算平均值,指定条件大于60的结果进行汇总SELECT 查询结果:学号,AVG(成绩)FROM 从那张表获取数据: scoreGROUP BY 学号HAVING AVG(成绩)>60;*/

SELECT 学号,AVG(成绩) FROM score GROUP BY 学号 HAVING AVG(成绩)>60;

-- 查询至少选择两门课程的学生学号/*译大白话:对学生表中根据学号分组,然后对分组结果中的学号计算课程号数量,指定条件数量大于等于2的结果进行汇总SELECT 查询结果:学号,COUNT(DISTINCT 课程号)FROM 从那张表获取数据: scoreGROUP BY 学号HAVING COUNT(DISTINCT 课程号)>=2;*/

SELECT 学号,COUNT(DISTINCT 课程号) FROM score GROUP BY 学号 HAVING COUNT(DISTINCT 课程号)>=2;

-- 查询同名同性学生名单并统计同名人数/*译大白话:对学生表中根据姓名、性别分组,然后对分组结果中的学号计数,指定条件数量大于等于2的结果进行汇总SELECT 查询结果:姓名,性别,COUNT(DISTINCT 学号)FROM 从那张表获取数据: studentGROUP BY 姓名,性别HAVING COUNT(DISTINCT 学号)>=2;*/

SELECT 姓名,性别,COUNT(DISTINCT 学号) FROM student GROUP BY 姓名,性别 HAVING COUNT(DISTINCT 学号)>=2;

-- 查询不及格的课程并按照课程号从大到小排序/*译大白话:在成绩表中根据课程号查询条件为成绩小于60分的课程,并将课程号降序排列SELECT 查询结果:课程号FROM 从那张表获取数据: scoreWHERE 成绩<60ORDER BY 课程号 DESC;*/

SELECT 课程号 FROM score WHERE 成绩<60 ORDER BY 课程号 DESC;

-- 查询每门课程的平均成绩,结果按照平均成绩升序排序;平均成绩相同时,按照课程号降序排列/*译大白话:在成绩表中根据课程号分组,对分组结果计算平均成绩,对计算结果汇总升序排列;如果均值相同按照课程号降序排列SELECT 查询结果:课程号,AVG(成绩)FROM 从那张表获取数据: scoreGROUP BY 课程号ORDER BY AVG(成绩) DESC,课程号 ASC;*/

SELECT 课程号,AVG(成绩) FROM score GROUP BY 课程号 ORDER BY AVG(成绩) DESC,课程号 ASC;

好啦~ 本次的分享先到这里,后续会继续更新~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值