6、MySQL数据库-分组函数

六、分组函数

1.分组函数

注意:分组函数自动忽略空值,不需要手动的加where条件排除空值。

  • select count(*) from emp where xxx; 符合条件的所有记录总数。
  • select count(comm) from emp; comm这个字段中 不为空 的元素总数。

注意:分组函数不能直接使用在where关键字后面。

  • mysql> select ename,sal from emp where sal > avg(sal);
  • ERROR 1111 (HY000): Invalid use of group function
1.1 count
# 取得所有的员工数, count(*)表示取得所有记录,为null的值也会取得
select count(*) from emp;

# 取得津贴不为null员工数, 采用count(字段名称),不会取得为null的记录
select count(comm)from emp;

# 取得工作岗位的个数
select count(distinct(job)) from emp;
1.2 sum
  • sum可以取得某一个列的和,null会被忽略
# 取得薪水的合计
select sum(sal) from emp;

# 取得津贴的合计, null会被忽略
select sum(comm) from emp;

# 取得公司支出薪水的合计(sal+comm)
select sum(sal+comm) from emp; # 不正确
# 不正确,原因在于comm字段有null值,所以无法计算,sum会忽略掉,正确的做法是将comm字段转换成0
select sum(sal+IFNULL(comm, 0)) from emp;

1.3 avg
  • 取得某一列的平均值
# 公司平均薪水
select avg(sal) from emp;
1.4 max
  • 取得某个一列的最大值
# 取得最高薪水
select max(sal) from emp;

# 取得最晚入职得员工(可以不使用str_to_date转换)
select max(str_to_date (hiredate, '%Y-%m-%d')) from emp;
select max(hiredate) from emp;
1.5 min
# 取得最低薪水
select min(sal) from emp;

# 取得最早入职得员工(可以不使用str_to_date转换)
select min(str_to_date(hiredate, '%Y-%m-%d')) from emp;
1.6 组合聚合函数
  • 可以将这些聚合函数都放到 select 中一起使用
select count(*),sum(sal),avg(sal),max(sal),min(sal) from emp;
1.7 和去重搭配使用(DISTINCT)
select count(distinct job) from emp;
1.8 分组函数能不能放在where语句后面?不能,因为是where先执行
select sal from emp where sal>avg(sal);

2. 分组查询

2.1 group by
# 求出emp中各部门的平均工资
select depno,avg(sal) from emp group by depno order by deptno;

# 取得每个工作岗位的工资合计,要求显示岗位名称和工资合计
select job, sum(sal) from emp group by job;

# 按照工作岗位和部门编码分组,取得的工资合计
select job,deptno,sum(sal) from emp group by job,deptno;
2.1.1以下SQL语句在Oracle数据库中无法执行,执行报错。在Mysql数据库中可以执行,但是执行结果矛盾。
select empno,deptno,avg(sal) from emp group by deptno;

在SQL语句中若有group by 语句,那么在select语句后面 只能分组函数 + 参与分组 的字段。

2.1.2如果使用了order by,order by必须放到group by后面

在这里插入图片描述

2.2 having
# 取得每个岗位的平均工资大于2000
select job, avg(sal) from emp group by job having avg(sal) > 2000;
2.3 select语句总结

一个完整的select语句格式如下

select 字段
from 表名
where …….
group by ……..
having …….(就是为了过滤分组后的数据而存在的—不可以单独的出现)
order by ……..

以上语句的执行顺序

  • 1.首先执行where语句过滤原始数据
  • 2.执行group by进行分组
  • 3.执行having对分组数据进行操作
  • 4.执行select选出数据
  • 5.执行order by排序

原则:能在where中过滤的数据,尽量在where中过滤,效率较高。having的过滤是专门对分组之后的数据进行过滤的。

3. 分组查询-进阶

3.1 简单的分组查询
# 1.查询每个岗位的最高工资
SELECT MAX(sal),job FROM emp GROUP BY job;

# 2.查询每个部门的员工个数
# 分析1
SELECT deptno FROM emp ORDER BY deptno;
# 分析2
SELECT COUNT(*),deptno FROM emp GROUP BY deptno;
3.2 添加简单筛选条件
# 3.查询名字中包含A字符的,每个部门的最高工资
# 分析1:每个部门的最高工资
SELECT MAX(sal),deptno FROM emp GROUP BY deptno;
# 分析2:查询名字中包含A字符的,每个部门的最高工资
SELECT MAX(sal),deptno FROM emp WHERE ename LIKE '%A%' GROUP BY deptno;

# 4.查询有奖金的每个领导手下员工的最高工资
# 分析1:每个领导手下员工的最高工资
SELECT MAX(sal),mgr FROM emp GROUP BY mgr;
# 分析1:查询有奖金的每个领导手下员工的最高工资
SELECT MAX(sal),mgr FROM emp WHERE comm IS NOT NULL AND comm>0 GROUP BY mgr;
3.3 添加复杂筛选条件–分组后筛选
# 5.查询那个部门的员工个数>2
# 分析1:每个部门的员工个数
SELECT COUNT(*),deptno FROM emp GROUP BY deptno
# 分析1:每个部门的员工个数>2
SELECT COUNT(*),deptno FROM emp GROUP BY deptno HAVING COUNT(*)>2

# 6.每个部门有奖金的员工的最高工资>1500的部门编号和最高工资
# 分析1:每个部门的员工部门编号和最高工资
SELECT deptno,MAX(sal) FROM emp GROUP BY deptno
# 分析2:每个部门有奖金的员工部门编号和最高工资
SELECT deptno,MAX(sal)FROM emp WHERE comm IS NOT NULL AND comm>0 GROUP BY deptno
# 分析3:每个部门有奖金的员工的最高工资>1500的部门编号和最高工资
SELECT deptno,MAX(sal) FROM emp WHERE comm IS NOT NULL AND comm>0 GROUP BY deptno HAVING MAX(sal)>1500

# 7.查询领导编号>7788的每个领导手下的最低工资大于2000的最低工资
SELECT ename,MIN(sal),mgr,deptno FROM emp WHERE mgr > 7788 GROUP BY mgr HAVING MIN(sal) > 2000;
            数据源         关键字      位置
分组前筛选  原始表          WHERE       FROM后面
分组后筛选  分组后结果集    HAVING      GROUP BY后面
特点:(1)分组函数做条件一定放在HAVING语句中
      (2)能在分组前做筛选的尽量在分组前做筛选
3.4 按函数分组
# 8.查询按员工姓名长度分组,查询每一组的员工个数,筛选员工个数>5的分组
# 分析1:按员工姓名长度分组,查询每一组的员工个数
SELECT COUNT(*),LENGTH(ename) FROM emp GROUP BY LENGTH(ename)
# 分析2:按员工姓名长度分组,查询每一组的员工个数,筛选员工个数>5的分组
SELECT COUNT(*),LENGTH(ename)  FROM emp GROUP BY LENGTH(ename) HAVING COUNT(*)>5
SELECT ename,LENGTH(ename) FROM emp ORDER BY LENGTH(ename)

3.4 可以用重命名
SELECT COUNT(*) c,LENGTH(ename) len_name FROM emp GROUP BY len_name HAVING c>5
3.5 能支持排序
# 9.查询没有奖金的员工的最高工资>2900的部门编号和最高工资,按最高工资升序
SELECT deptno,MAX(sal) AS m FROM emp WHERE comm IS NULL GROUP BY deptno HAVING m>2900 ORDER BY m
3.6 能支持多个字段进行分组
# 10.查询每个部门每个工作岗位的最低工资,并按最低工资降序
SELECT deptno,job,MIN(sal) FROM emp GROUP BY deptno,job ORDER BY MIN(sal) DESC;

SELECT deptno,job,sal FROM emp ORDER BY deptno DESC;


# 11.取得每个岗位的平均工资大于2000的员工
SELECT * FROM emp
# 12.取得每个岗位的平均工资
SELECT AVG(SAL),job FROM emp GROUP BY job HAVING AVG(SAL)>2000
发布了29 篇原创文章 · 获赞 52 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/qq_42250189/article/details/105169224
今日推荐