【转】想要弄懂GROUP BY看这一篇就够了

想要弄懂GROUP BY看这一篇就够了

Java程序员的奋斗路 2020-12-22 09:38

前言

group by 关键字,不管是工作中还是面试都会经常被用到,所以弄懂它是非常有必要的。要弄懂group by 那我们就得联合着:聚合函数、group by 、having 一块讲解。

讲之前我们先准备一张表:

聚合函数

为了讲好group by我们必须先将聚合函数,所以大家别着急,一步步往下看。

聚合函数是将“若干行数据”经过计算后聚合成“一行数据”

常用的聚合函数:

1.MAX:返回某列的最大值 
2.MIN(column)	返回某列的最高值 
3.COUNT(column)	返回某列的总行数 
4.COUNT(*)	返回表的总行数
5.SUM(column)	返回某列的相加总和
6.AVG(column)	返回某列的平均值

下面我们简单使用一下这些聚合函数。

  1. MAX和MIN函数

我们计算一下员工表中最大工资和最小工资。

select Max(sal) , Min(sal) from emp;

  1. SUM和AVG函数

我们计算一下工资总和和平均工资。

select sum(sal),avg(sal) from emp;

3.COUNT函数

count函数是计算总行数。count(*)是计算表中总行数。count(列名)是计算某一列的总行数(不包括null值)。

select count(*),count(comm) from emp;

细心的小伙伴可能已经发现了,为什么count(*)和count(comm)的值不一样呢?

答案是:聚合函数只作用非null,因为null数据不参与运算。

请大家在使用聚合函数的时候一定要记住这一点,不然计算的结果可能不是你想要的。我们以奖金的平均值来做测试,代码如下:

select avg(comm),avg(ifnull(comm,0)) from emp;

为啥同样是计算comm表明的平均值,但是计算出来的值不一样呢?

上面我们提过null在聚合函数中不参与计算。所以:

avg(comm)只计算了4个人的奖金(关羽,张飞,貂蝉,吴用)取平均值。

而avg(ifnull(comm,0))却是计算了所有人的奖金,取平均值。所以值要小的多,这其中的关键就是用了ifnull() 函数(ifnull函数的作用就是发现值为null后将其值变为0)。

温馨提示:聚合函数使用时注意空值的情况,要配合ifnull函数使用哦~

现在再回头看看select count(*),count(comm) from emp;这个语句,是不是就明了多了。

好,聚合函数我们就讲到这里,其实也没什么难的是不是。下面我们开始讲group by。

GROUP BY

GROUP BY 语句根据一个或多个列对结果集进行分组。在分组的列上我们通常配合 COUNT, SUM, AVG等函数一起使用。

为了方便大家观看,我把员工表拿到这里来,我们先以job分组执行一下看看。

select job ,group_concat(ename) from emp group by job;

看到没有按照job分组后,我们会自动的按照job字段归类。group_concat函数是将归类后的名字以逗号连接成字符串,这个函数大家了解就行,我这里仅仅是让大家看的更明白。

下面我们有这样一个需求:

求每个部门所有工资总和。

简简单单的一句话,光用where是很难做到的。但是group by 就非常简单。代码如下:

select deptno,sum(sal) from emp group by  deptno;

我们通过deptno字段对表数据进行分组后,然后通过sum(sal)来计算每个分组的总和。

我们再做一个难点的练习:查询每个部门工资大于1500的的人数。

这个是不是有难度了,我们一点点拆分来做。

1.每个部门:按照deptno分组,
   select deptno from emp group by deptno;
2.工资大于1500:where sal >1500
3.人数:count(*)函数。

这样一拆分是不是明了多了,我们写出语句:

select deptno,count(*) from emp where sal >1500 group by deptno;

好,group by就讲到这里,下面我们接着讲having.

HAVING

HAVING用于分组后的再次筛选,只能用于分组。(注意:分组后)

练习:求工资总和大于9000的部门,并按照工资总和排序。

这个问题是接上面:“求每个部门所有工资总和”,再加一条分组后的筛选。sql语句如下:

select deptno,sum(sal)  total  from emp group by  deptno having sum(sal) >9000 
order by sum(sal) asc;

having和where区别:

   1.having是分组后,where是分组前
   2.where不用使用聚合函数,having可以使用聚合函数。
   3.where在分组之前就会进行筛选,过滤掉的数据不会进入分组。

关键字的执行顺序总结

关键字的书写顺序如下:

		1.select 
		2.from
		3.where
		4.group by
		5.having
		6.order by
		7. limit

关键字的执行顺序如下:

    1.from	//行过滤
		2.where
		3.group by
		4.having
		5.select	//列过滤
		6.order by//排序
		7.limit//附加

还是以员工表为例,我们以下面这条语句为例子逐步解析一下。

select deptno,sum(sal)  total  from emp where sal>1000 group by  deptno having sum(sal) >9000 
order by sum(sal) asc;

结果如下:

第一步:执行from关键字

等同于执行语句:select *  from emp;

第二步:在第一步的基础上执行where

等同于:select deptno from emp where sal >1000;

第三步:在第二步的基础上执行group by

等同于:select deptno from emp where sal >1000 group by deptno;

第四步:在第三步的基础上执行having

等同于:select deptno from emp where sal >1000 group by deptno having sum(sal) >9000;

第五步:在第三步的基础上选择列。

等同于:select deptno,sum(sal)  total from emp where sal >1000 
group by deptno having sum(sal) >9000;

第六步:order by 排序(略)

第七步:limit(略)

结尾

好了,本章就讲到这里吧。

感谢关注我,小编会持续输出优质内容!

猜你喜欢

转载自blog.csdn.net/jessezappy/article/details/131189750
今日推荐