当前位置: 首页 > 科技观察

groupby在数据库中的用法示例

时间:2023-03-19 20:01:08 科技观察

前段时间面试的时候遇到这样一道面试题,因为很久没有接触SQL了,所以没有写出来。如图,有这样一张评分表:首先,我们要明白groupby的含义:“GroupBy”字面意思就是按照“By”规定的规则对数据进行分组。所谓分组就是将一个“数据集”分成若干个“小区域”,然后对若干“小区域”进行数据处理。我们先看这样一条sql语句:selectsubject,max(score)fromgradeGROUPBYsubject结果是:这样就正确的得到了每个科目的最高分和科目名称。是不是可以通过在学生名字后面加个名字得到对应的学生名字呢?我们可以试试:selectsubject,max(score),namefromgradeGROUPBYsubject看到结果觉得成功了,但是对比数据后发现不对,学生的名字和分数不对对应。如果你认为成功是因为你对groupby不够了解,我不知道为什么这个查询能出结果。我用的mysql数据库如果是oracle会报错。注意:因为select中指定的字段要么包含在GroupBy语句之后,作为分组依据;或者它必须包含在聚合函数中。所以这是错误的。groupby语句中select指定的字段必须是“groupby字段”。如果其他字段要出现在select中,则必须将它们包含在聚合函数中。常用的聚合函数如下:函数支持sum(列名)summax(列名)最大值min(列名)最小值avg(列名)平均值first(列名)仅第一条记录Access支持last(列名)name)lastrecordonlyAccess支持count(columnname)统计注意记录数和count(*)的区别我们还是分析需求,通过需求写SQL语句。这里有几种方法:我们通过groupby分组得到每个科目的最高分和科目名,作为SQL的第一句,然后查询分数表,找到科目和分数相同的记录:(子sql语句是主sql语句的一部分)#a.*表示a表所有字段,b.*表示b表所有字段selectb.*from(selectsubject,max(score)mfromgradeGROUPBYsubject)t,gradebwheret.subject=b.subjectandt.m=b.score结果如下:对比表明数据正确。扩展提问法:用一句SQL找出所有课程中成绩最高和最低的学生及其成绩。首先,通过分组获取每个科目的最高分和最低分:selectsubject,max(score),MIN(score)fromgradeGROUPBYsubject结果如下:我们如何将最高分对应的学生姓名与把最低分的名字填进去,要求的数据显示是分数最高的一行和分数最低的一行。所以这行不通。通过上面第一题得到的思路:selectb.*from(selectsubject,max(score)mfromgradeGROUPBYsubject)t,gradebwheret.subject=b.subjectandt.m=b.score这样,既然可以得到每个科目的最高分,学名,科目名,那你是不是也可以把max(分数)改成min(分数),得到最低分,学生名,科目名?现在的重点是如何将两条SQL语句的结果合而为一。selectb.*from(selectsubject,min(score)mfromgradeGROUPBYsubject)t,gradebwheret.subject=b.subjectandt.m=b.score这时候就想到了sql的关键字:UNION的定义UNION运算符用于合并两个或多个SELECT语句的结果集。请注意,UNION内的SELECT语句必须具有相同的列数。列也必须具有相似的数据类型。此外,每个SELECT语句中列的顺序必须相同。注意:默认情况下,UNION运算符选择不同的值。如果允许重复值,就用UNIONALL。此外,UNION结果集中的列名始终等于UNION中第一个SELECT语句中的列名。所以得到的sql是这样的:selectb.*from(selectsubject,max(score)mfromgradeGROUPBYsubject)t,gradebwheret.subject=b.subjectandt.m=b.scoreUNIONselectb。*from(selectsubject,min(score)mfromgradeGROUPBYsubject)t,gradebwheret.subject=b.subjectandt.m=b.score结果是:这样就可以了。如果你还想添加一些东西。例如,添加一列以指示分数是最低还是最高。选择b.*,"highestscore"from(selectsubject,max(score)mfromgradeGROUPBYsubject)t,gradebwheret.subject=b.subjectandt.m=b.scoreUNIONselectb.*,"lowestscore"from(selectsubject,min(score)mfromgradeGROUPBYsubject)t,gradeb其中t.subject=b.subject和t.m=b.score