009、分组查询(group by)
分组查询(group by)
# -------------------------9、分组查询 ------------------------- # 取得每个工作岗位的工资合计,要求显示岗位名称和工资合计。 select * from emp; select job, sum(sal) from emp group by job; # 按照工作岗位和部门编码分组,取得的工资合计 # 在 SQL 语句中若有 group by 语句,那么在 select 语句后面只能跟分组函数+参与分组的字段。 select deptno, job, sum(sal) from emp group by deptno, job; # 取得每个岗位的平均工资大于 2000 # 有group by语句,后面不能有where select job, avg(sal) from emp group by job having avg(sal)>2000;
知识扩展:
分组查询group by的用法及讲解
参考资料:https://baijiahao.baidu.com/s?id=1664040284917893293&wfr=spider&for=pc
group by是sql中比较强大的功能,是在对数据分组统计时必不可少的用法。但是,对于很多经验不足的同学,经常会写错。今天我们就以Oracle为例,来讲解下分组查询group by的用法。
一,group by 语法规范
首先我们准备一张Student表
CREATE TABLE STUDENT
( SNO VARCHAR2(10) not null,
SNAME VARCHAR2(20),
SAGE NUMBER(2),
SSEX VARCHAR2(5) )
往里面插入几条学生实体记录。再查看数据:
SELECT * FROM STUDENT;
我们使用group by将这些数据按照性别进行分组:
SELECT * FROM STUDENT GROUP BY SSEX;
不幸的是,执行失败了,提示:不是 GROUP BY 表达式!(我用navicat 连接mysql 执行 SELECT * FROM t_student GROUP BY sex; 成功啊!不过还是按照他的思路搬运过来先,或许Oracle不行呢。)
原因是group by 分组查询,select子句后的字段必须来自group by后的分组字段。于是 我们执行SQL
SELECT SSEX FROM STUDENT GROUP BY SSEX;
这下成功地将数据分为了两组。我们接下来使用下聚合函数
SELECT SSEX,MAX(SAGE) FROM STUDENT GROUP BY SSEX;
注意这条sql语句,select子句中聚合函数使用了SAGE(年龄)这个字段,那会不会违背了前面所说的 “select子句后的字段必须来自group by后的分组字段”这个规律呢,我们来执行一下:
能正常执行,成功地按照了性别分组,并且查询出了性别对应年龄最大的学生。于是我们可以得出规律:select子句后的任一非聚合函数字段都应来源于group by 分组语句后,否则语法会编译不通过。
二,group by 用法的意义
我们都知道group by 是用来分组的,那么具体怎么分组,对应的语句又怎么写呢?我们一起来研究下。
示例:按照年龄将学生分组。
很多人会这样写:
SELECT * FROM STUDENT GROUP BY SSAGE
上面已经证实过了,这样子语法不通过。
SELECT SSAGE FROM STUDENT GROUP BY SSAGE
如果这样写的话,也只会单纯地将年龄分组。
正确的写法是这样的:
SELECT SNAME,SAGE FROM STUDENT GROUP BY SAGE,SNAME ORDER BY SAGE;
可以看出,group by 分组是按照group by后的字段组合来进行分组的。也就是说你group by后给了我几个字段,我就按照这几个字段组合成一条记录,若有重复的记录,就属于同一组,最后将所有的分组返回给你。
同时上诉sql的order by语句也要符合group by的语法,即order by后的字段必须来源于group by分组字段。所以我们可以把分出来的组理解为试图,所有的其他操作都基于这张视图。
三,分组查询的筛选where和having
示例:查询出性别为男的学生并按照年龄分组,并筛选出年龄大于21岁的
我们首先实现钱半部分:查询出性别为男的学生并按照年龄分组
SELECT SNAME,SAGE FROM STUDENT where SSEX='男' GROUP BY SNAME,SAGE
然后使用having语句筛选:
SELECT SNAME,SAGE FROM STUDENT where SSEX='男' GROUP BY SNAME,SAGE HAVING SAGE>'21'
查询结果:
可以看到,小于等于21岁的男同学都被过滤掉了。
我们这里可以进行总结下:
1. 当在一个SQL中同时使用where和group by和having子句时,其执行顺序为:where>group by>having。
2. 同时where子句作用于表或者视图,having子句作用于组,having子句必须作用在group by之后。
以上三点就是分组查询group by的用法及讲解。